Top Banner
Win32 API System Programming GDI & GDI+ 한한한한한 한한한한한한 Computer Vision & Pattern Recognition Lab 한한 5 한 한한
136

Win32 API System Programming

Jan 11, 2016

Download

Documents

JEB

Win32 API System Programming. GDI & GDI+. 한양대학교 컴퓨터공학과 Computer Vision & Pattern Recognition Lab 박사 5 기 박현. Contents. GDI Device Context 다양한 그리기 함수 속성 설정 매핑 모드 예제 GDI+ 구성요소 새로운 기능 프로그래밍 모델에서의 변화 사용방법 예제. GDI. GDI ( Graphic Device Interface ) - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Win32 API System Programming

Win32 API System Programming

GDI & GDI+

한양대학교 컴퓨터공학과 Computer Vision & Pattern Recognition Lab

박사 5 기 박현

Page 2: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 2

Contents

GDI Device Context

다양한 그리기 함수

속성 설정

매핑 모드

예제

GDI+ 구성요소

새로운 기능

프로그래밍 모델에서의 변화

사용방법

예제

Page 3: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 3

GDI

GDI ( Graphic Device Interface ) Window OS 상의 풍부한 그리기 작업을 제공하는 인터페이스

장치 독립적인 그래픽 출력 모델 ( GDI + Graphic Device Driver )

GDI 서비스 : Gdi.exe , Gdi32.dll

GDI Object Pen, Brush , Bitmap , Region, Font , Palette

GDI Object 는 프로그램 종료 시 자동으로 삭제되지 않음

Device Context 에서 사용되고 있는 GDI Object 는 DeleteObject 에 의해서

삭제되지 않음

Application Graphic HardwareGDI

Virtual Device Driver

Page 4: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 4

GDI

GDI 관련 함수 Device Context 의 속성 관련 함수

도형 관련 출력 함수

Text 관련 출력 함수

Mapping mode 관련 함수

그림 도구 변경 함수

DC( Device Context ) GDI 의 핵심적인 개념

GDI 함수의 Parameter 로 쓰인다 .

논리적 “스크린” , “ 프린터” 등을 표시함

구조체 : 객체 + 속성 + 모드

Page 5: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 5

Device Context

DC

Simple Method

OnPaint Handler

CDC * pDC = GetDC();

// Drawing

ReleaseDC( pDC );

PAINTSTRUCT ps;

CDC * pDC = BeginPaint( &ps );

//Drawing

EndPaint( &ps );

Page 6: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 6

Device Context Class

Motive

DC 를 얻거나 해제하기 위한 함수를 기억해야 함

사용한 DC 를 확실하게 해제해야 함

PAINTSTRUCT ps;

CDC * pDC = BeginPaint( &ps );

//Drawing

EndPaint 함수를 사용하지 않았다면 ???

Page 7: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 7

Device Context Class

CDC

CPaintDC

OnPaint 핸들러

CWnd::BeginPaint() ~ CWnd::EndPaint();

BeginPaint() 또는 EndPaint() 호출시 실패 ????

CPaintDC::m_ps PAINTSTRUCT 의 rcPaint

Page 8: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 8

Device Context Class

CDC CWindowDC

CWindowDC dc(this) : ( Client Area + Frame ) CWindowDC dc(NULL) : Screen Area CWnd::GetWindowDC() ~ CWnd::ReleaseDC();

NonClient Area 에 효과를 주기 위해 사용함 CWindowDC 보다는 WM_NCPAINT 메시지 핸들러를 더 사용함

CClientDC CClientDC dc(this) : Client Area CClientDC dc(NULL) : Screen Area CWnd::GetClientDC() ~ CWnd::ReleaseDC();

CMetaFileDC 메타파일에 대한 그리기 작업 Construct : Create() ~ Destructor : DeleteMetaFile()

Page 9: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 9

Drawing Function

Function Description

LineTo Current Position 에서부터 라인을 그린다 .

Rectangle 사각형을 그린다 .

RoundRect 모서리가 둥근 사각형을 그린다 .

Ellipse 원이나 타원을 그린다 .

Pie 파이 모양의 쐐기를 그린다 .

Polygon 점들의 배열을 연결하는 다각형을 그린다 .

PolyBezier 점들의 배열로부터 베지어 스플라인을 그린다 .

CDC Draw Function

Page 10: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 10

DC Property

속성 기본값 설정함수 추출함수

텍스트색상 Black CDC::SetTextColor CDC::GetTextColor

배경색 White CDC::SetBkColor CDC::GetBkColor

배경모드 OPAQUE CDC::SetBkMode CDC::GetBkMode

매핑포드 MM_TEXT CDC::SetMapMode CDC::GetMapMode

그리기모드 R2_COPYPEN CDC::SetROP2 CDC::GetROP2

펜위치 (0,0) CDC::MoveTo CDC::GetCurrentPosition

펜 BLACK_PEN CDC::SelectObject CDC::SelectObject

브러쉬 WHITE_BRUSH CDC::SelectObject CDC::SelectObject

글꼴 SYSTEM_FONT CDC::SelectObject CDC::SelectObject

CDC::SelectStockObject

Page 11: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 11

Mapping Mode

Logical Coordinate MoveTo , LineTo : 실질적인 화면의 좌표가 아님

Device Context 에 의해서 정의되는 논리적 좌표계의 좌표

CDC::SetWindowOrg

Device Coordinate GDI : 장치 속성 , 매핑모드 방정식을 이용 논리적 좌표를 화면의

실질적 좌표 (Device Coordinate) 로 변경

원점 : Device Context 의 Display 표면의 (0,0)

단위 : 픽셀

CDC::SetViewPortOrg

(0,0)

Page 12: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 12

Mapping Mode

CDC::SetViewPortOrg

Logical Coordinate (0,0) => Mapping to Device Coordinate(x,y)

CDC::SetWindowOrg

Logical coordinate(x,y) => Mapping to Device Coordinate(0,0)

(0,0)

(x,y) Device Unit

(0,0) Logical Coordinate Origin

(x,y) Device Unit

(0,0)

(x,y) Logical coordinate

(0,0)

(x,y) Logical coordinate

Page 13: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 13

Mapping Mode

CDC::SetMapMode

Page 14: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 14

GDI+

GDI+

For Window XP Graphic Device Interface

GDI+ API provide C++ Class for GDI+

GDI+ 의 세가지 구성요소 2D Vector Graphics

Image processing

Typography

Page 15: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 15

GDI+

GDI+ 의 세가지 구성요소

2D Vector Graphics

여러 점들로 구성되는 Drawing Primitives 가 존재

Drawing Primitives 에 대한 정보를 저장하는 Class 제공

Rect , Point , Pen , Brush , Graphics

Image processing

Vector Image Processing

다양한 Image 관련 객체들 ( CachedBitmap )

Typography

다양한 형태의 크기 , 폰트 , 스타일로 TEXT 출력 하는 것과 관련됨

Font Antialiasing 기능 제공

Page 16: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 16

GDI+

GDI+ 의 새로운 특징들 Gradient Brushes

Cardinal Splines

Independent Path Objects

Transformations and the Matrix Object

Scalable Regions

Alpha Blending

Antialiasing

Support for Multiple Image Formats

Etc..

Page 17: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 17

GDI+ 새로운 기능

Gradient Brushes

Brush : 도형 , 패스 (Path) , 영역 (Region)

점진적으로 색상이 변함

Linear gradient brush

두가지 색상만 제공함

Path gradient brush

경로에 따라 색상의 변화를 정의

Page 18: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 18

GDI+ 새로운 기능

Cardinal Splines GDI 에 없던 Cardinal Spline 을 제공함

Independent Path Objects ( Path Object’s Durability )

GDI

DC 와 밀접한 Path 는 한번 그려지면 정보가 모두 소멸됨

GDI+

Graphics 객체와 독립적인 Path 객체가 정보 유지함

Path 객체를 여러 개 생성하여 유지할 수 있음 .

Page 19: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 19

GDI+ 새로운 기능

Transformation & Matrix Object

Matrix Object

쉬우면서 유연한 Transformation (Translate , Rotate, etc) 기능을 제공함

Matrix Object 는 Transform 되어야 할 객체와 결합하여 사용됨 .

GraphicsPath 객체는 Transform 함수를 가지고 있음 .

Region + Matrix Object

Page 20: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 20

GDI+ 새로운 기능

Scalable Region

GDI

Device Coordinate 상의 정보로 저장됨

Translation 변환만 가능함

GDI+

World coordinate ( 무한좌표계 )

Scaling , Translation , Rotation

Page 21: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 21

GDI+ 새로운 기능

Alpha Blending

Transparency 설정

Antialiasing

계단현상을 줄임

Page 22: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 22

GDI+ 새로운 기능

Recoloring

Image Color Adjusting Process

changing one color to another

adjusting a color's intensity relative to another color

adjusting the brightness or contrast of all colors

converting colors to shades of gray

Page 23: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 23

GDI+ 새로운 기능

Graphics Container

Graphics Object : Container 역할

Graphics State 정보를 유지

Outer Container

Inner ContainerAntialiasing mode

Page 24: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 24

GDI+ 새로운 기능

Various Image format

GDI+ 는 Image, Bitmap, Metafile 클래스들을 제공함 .

BMP

GIF

JEPG

Exif

PNG

TIFF

ICON

WMF

EMF

Page 25: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 25

GDI+ Programming Model

GDI Device Context 사용하는 Handle 기반 SelectObject Function 에 의해서 영향을 받음 .

Current Position

Brush 에 의해서 도형의 내부가 칠해짐 Resion 및 Path 정보는 단발성

GDI+ Graphics 객체를 사용하는 객체지향적인 모델 사용중인 Pen , Brush , Bitmap , Font 에 정보를 유지하지 않음 그래픽 객체를 인수로 사용함 Overloading 된 많은 함수들을 제공 Current Position 개념을 지원하지 않음 도형의 외곽선을 그리는 함수와 내부를 칠하는 함수를 분리 Region 과 Path 기능 강화

Page 26: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 26

GDI+ Programming Model

In MFC

StdAfx.h #ifndef ULONG_PTR

#define ULONG_PTR unsigned long *

#endif

#include <Gdiplus.h>

#include <GdiplusBase.h>

#include <GdiplusColor.h>

#include <GdiplusPen.h>

#include <GdiplusBrush.h>

#include <GdiplusPath.h>

#include <Gdiplusgraphics.h>

using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")

Page 27: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 27

GDI+ Programming Model

In MFC

CWinApp

Member Variable

ULONG_PTR m_gdiplusToken;

InitInstance()

GdiplusStartupInput gdiplusStartupInput;

// Initialize GDI+

GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

ExitInstance()

GdiplusShutdown(m_gdiplusToken);

Page 28: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 28

GDI+ Coordinate Systems

Types of Coordinate Systems

World Coordinate System

Page Coordinate System

Device Coordinate System

Transformation Sequences of Coordinate

Before GDI+ can draw the line on screen

World Coordinate Page Coordinate Device Coordinate

Page 29: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 29

GDI+ Coordinate Systems

GDI+ World Coordinate System

원점은 Transform 에 의해서 변경됨 .

GDI+ Function Call : graphics.DrawLine( &penBlack , 0 , 0 , 160 , 80 );

Page Coordinate System

원점은 항상 클라이언트 영역의 (0,0) 이다 . ( 변경되지 않음 )

기본 단위 : 픽셀 ( Page Coordinate System = Device Coordinate System )

기본 단위 변경 가능

Device Coordinate System

원점은 항상 클라이언트 영역의 (0,0) 이다 . ( 변경되지 않음 )

기본단위 : 픽셀

Page 30: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 30

GDI+ Coordinate Systems

GDI+ ( 100 , 50 ) 을 원점으로 하는 좌표계

Page 31: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 31

GDI+ Coordinate Systems

Mapping

World Transformation

Map World Coordinates to Page Coordinates

Graphics 객체에 의해서 정보가 유지됨 .

TranslateTransform 을 이용함 .

World Coordinate Page Coordinate

World Transformmation

graphics.TranslateTransform( 100.0f , 50.0f );

graphics.DrawLine( &myPen , 0 , 0 , 160 , 80 );

Page 32: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 32

GDI+ Coordinate Systems

Mapping

Page Transformation

Map Page Coordinates to Device Coordinates

Graphics 객체에 의해서 정보가 유지됨 .

SetPageUnit, GetPageUnit , SetPageScale, GetPageScale 을 이용함 .

Page Coordinate Device Coordinate

Page Transformmation

graphics.SetPageUnit( UnitInch );

graphics.DrawLine( &myPen , 0 , 0 , 2, 1);

Page 33: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 33

GDI+ Coordinate Systems

Mapping

Page Transformation

Pen 의 굵기를 변경하지 않으려면 GetDpiX , GetDpiY 함수를 이용 .

GetDpiX , GetDpiY : Pixel per Inch 를 얻어온다 .

graphics.DrawLine( &myPen , 0 , 0 , 2, 1); in 96 dots per inch

Pen myPen(Color(255,0,0,0) , 1 / graphics.GetDpiX() );

Page 34: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 34

GDI+ Coordinate Systems

Mappinggraphics.TranslateTransform( 2.0f , 0.5f );

graphics.SetPageUnit( UnitInch );

graphics.DrawLine( &myPen , 0 , 0 , 2, 1);

Page 35: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 35

GDI+ Global and Local Transformation

Matrix Class

Multiply , Invert , Rotate , RotateAt , Scale , Shear , OffsetX OffsetY

Clone, Equals 등 다양한 함수를 제공함 .

Geometric Transformations

100

0cossin

0sincos

100

00

00

scaley

scalex

1

010

001

translateytranslatex

Rotate Scale Translate

Page 36: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 36

GDI+ Global and Local Transformation

Matrix Class// Create the path.

GraphicsPath myGraphicsPath;

Rect myRect(0, 0, 60, 60);

myGraphicsPath.AddRectangle(myRect);

// Fill the path on the new coordinate system.

// No local transformation

myGraphics.FillPath(&mySolidBrush1, &myGraphicsPath);

// Transform the path.

Matrix myPathMatrix;

myPathMatrix.Scale(2, 1);

myPathMatrix.Rotate(30, MatrixOrderAppend);

myGraphicsPath.Transform(&myPathMatrix);

myGraphics.FillPath(&mySolidBrush2, &myGraphicsPath);

Page 37: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 37

GDI+ Global and Local Transformation

Graphics class

MultiplyTransform , RotateTransform ,

ScaleTransform , TranslateTransform

graphics.DrawEllipse( &penBlue , 0 , 0 , 100 , 50 );

graphics.ScaleTransform( 1.0f , 0.5f );

graphics.TranslateTransform( 50.0f , 0.0f , MatrixOrderAppend );

graphics.RotateTransform( 30.0f , MatrixOrderAppend );

graphics.DrawEllipse( &penBlue , 0 , 0 , 100 , 50 );

Page 38: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 38

GDI+ : Pen

Pen

DrawLine , DrawRectangle , DrawEllipse , DrawPolygon , DrawArc ,

DrawCurve , DrawBezier

CClientDC dc(this);

Graphics graphics( dc.GetSafeHdc() );

Pen penBlack( Color(255,0,0) , 5 );

Status state = graphics.DrawRectangle( &penBlack , 10 , 10 , 100 , 50 );

Page 39: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 39

GDI+ : Pen

Pen

Width & Alignment

Status SetWidth ( REAL width );

Status SetAlignment( PenAlignment penAlignment );

PenAlignmentCenter = 0

PenAlignmentInset = 1

Pen penBlack( Color(255,0,0,0) , 1 );

Pen penGreen( Color(255,0,255,0) , 10 );

Status state = penGreen.SetAlignment(PenAlignmentCenter);

state = graphics.DrawLine( &penGreen, 10 , 100 , 100 , 50 );

state = graphics.DrawLine( &penBlack, 10 , 100, 100, 50 );

Page 40: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 40

GDI+ : Pen

Pen

Width & Alignment

Pen penBlack( Color(255,0,0,0) , 1 );

Pen penGreen( Color(255,0,255,0) , 10 );

Status state = penGreen.SetAlignment(PenAlignmentInset);

state = graphics.DrawRectangle( &penGreen, 10 , 100 , 50 , 50 );

state = graphics.DrawRectangle( &penBlack, 10 , 100, 50, 50 );

Page 41: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 41

GDI+ : Pen

Pen Line Caps

SetStartCap , SetEndCap

Cap Type

LineCapFlat = 0

LineCapSquare = 1

LineCapRound = 2

LineCapTriangle = 3

LineCapNoAnchor = 0x10

LineCapSquareAnchor = 0x11

LineCapRoundAnchor = 0x12

LineCapDiamondAnchor = 0x13

LineCapArrowAnchor = 0x14

LineCapCustom = 0xff

Page 42: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 42

GDI+ : Pen

Pen

LineCapArrowAnchor

Status state;

Pen penBlack( Color(255,0,0,0) , 5 );

state = penBlack.SetStartCap( LineCapArrowAnchor );

state = penBlack.SetEndCap( LineCapRoundAnchor );

state = graphics.DrawLine( &penBlack , 20 , 175 , 300 , 175 );

Page 43: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 43

GDI+ : Pen

Pen LineCapCustom

Pen member function

Status SetCustomStartCap( const CustomLineCap * customCap );

Status SetCustomEndCap( const CustomLineCap * customCap );

Class CustomLineCap

새로운 캡을 GraphicsPath 에 의해서 생성할 수 있음 .

CustomLineCap( const GraphicsPath * fillPath, const GraphicsPath * strokePath,

LineCap baseCap, REAL baseInset);

fillPath 와 strokePath 를 동시에 사용할 수 없음 .

fillPath 와 strokePath 를 동시에 사용하면 fillPath 가 무시됨 .

Page 44: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 44

GDI+ : Pen

Pen

LineCapCustom

Class CustomLineCap

Graphics graphics(hdc);

Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};

GraphicsPath capPath;

capPath.AddLines(points, 3);

CustomLineCap custCap(NULL, &capPath);

custCap.SetStrokeCaps(LineCapTriangle, LineCapRound);

Pen strokeCapPen(Color(255, 255, 0, 255), 5.0f);

strokeCapPen.SetCustomEndCap(&custCap);

graphics.DrawLine(&strokeCapPen, Point(100, 100), Point(300, 100));

Page 45: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 45

GDI+ : Pen

Pen

LineCapCustom

Class CustomLineCap

Based Vertical Line

0

-15

LineCapTriangle LineCapRound

Page 46: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 46

GDI+ : Pen

Pen

LineCapCustom

Class AdjustableArrowCap

화살표 캡과 비슷한 캡을 생성할 수 있음 .

AdjustableArrowCap( REAL height, REAL width, BOOL isFilled );

CustomLineCap

AdjustableArrowCap

BaseClass

SubClass

height

width

Page 47: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 47

GDI+ : Pen

Pen

LineCapCustom

Class AdjustableArrowCap

Graphics graphics(hdc);

AdjustableArrowCap myArrow(10, 10, true);

Pen arrowPen(Color(255, 0, 0, 0));

arrowPen.SetCustomEndCap(&myArrow);

graphics.DrawLine(&arrowPen, Point(0, 20), Point(100, 20));

AdjustableArrowCap otherArrow(myArrow.GetHeight(), 20, true);

arrowPen.SetCustomEndCap(&otherArrow);

graphics.DrawLine(&arrowPen, Point(0, 55), Point(100, 55));

Page 48: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 48

GDI+ : Pen

Pen

Dash Line

REAL dashValues[4] = {5, 2, 15, 4};

Pen blackPen(Color(255, 0, 0, 0), 5);

blackPen.SetDashPattern(dashValues, 4);

Status stat = graphics.DrawLine(&blackPen, Point(5, 5), Point(405, 5));

Page 49: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 49

GDI+ : Pen

Pen

Join Line

GraphicsPath path;

Pen penJoin(Color(255, 0, 0, 255), 8);

Status stat = path.StartFigure();

stat = path.AddLine(Point(50, 200), Point(100, 200));

stat = path.AddLine(Point(100, 200), Point(100, 250));

stat = penJoin.SetLineJoin(LineJoinBevel);

stat = graphics.DrawPath(&penJoin, &path);

Page 50: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 50

GDI+ : Pen

Pen

Texture Image 를 이용하여 도형을 그릴 수 있음 .

Status state;

Image image(L”Texture.jpg”);

TextureBrush brTexture(&image)

Pen penTexture(&brTexture , 10 );

state = graphics.DrawImage( &image , 0 , 0 ,

image.GetWidth(), image.GetHeight() );

state = graphics.DrawEllipse( &penTexture ,100,20,200,100);

Page 51: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 51

GDI+ : Brush

Brush

Type : solid , hatch pattern , image texture , color gradient

Function : FillRectangle , FillEllipse , FillRegion , FillPolygon ,

FillClosedCurve

SolidBrush brSolid(Color(255,255,0,0));

Status state = graphics.FillEllipse( &brSolid , 0 , 0 , 100 , 50 );

Page 52: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 52

GDI+ : Brush

Brush

Hatch Style

HatchStyleHorizontal , HatchStyleVertical , HatchStyleForwardDiagonal

HatchStyleBackwardDiagonal , HatchStyleCross , HatchStyleDiagonalCross

HatchBrush brHatch( HatchStyleHorizontal , Color(255,255,0,0)

, Color(255,128,255,255));

Status state = graphics.FillEllipse( &brHatch , 0 , 0 , 100 , 50 );

Page 53: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 53

GDI+ : Brush

Gradient Brush

LinearGradientBrush

Rect rect( 0 , 0 , 140 , 70 );

LinearGradientBrush brLGradient( rect ,

Color(255,255,0,0) ,

Color(255,0,0,255) ,

LinearGradientModeHorizontal );

graphics.FillEllipse( &brLGradient , rect );

Page 54: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 54

GDI+ : Brush

Gradient Brush

LinearGradientBrush

Point point1(0, 0);

Point point2(100, 80);

LinearGradientBrush brLGradient( point1, point2, Color(255, 255, 0, 0), Color(255, 0, 0, 255));

graphics. FillRectangle( &brLGradient , 0 , 0 , 100 , 80 );

Page 55: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 55

GDI+ : Brush

Path Gradient Brush

PathGradientBrush

GraphicsPath pathEllipse;

pathEllipse.AddEllipse(0,0,140,70);

PathGradientBrush brPathBrush( &pathEllipse );Color clrCenter( 255 , 0 , 0 , 255 );Color clrSurround( 255 , 200 , 255 , 255 );int nColor = 1;

brPathBrush.SetCenterColor( clrCenter );brPathBrush.SetSurroundColors( &clrSurround , &nColor );

graphics.FillPath( &brPathBrush , &pathEllipse );

Page 56: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 56

GDI+ : Brush

Path Gradient Brush

PathGradientBrush

PointF ptsF[] = {PointF(0, 0),

PointF(160, 0),

PointF(160, 200),

PointF(80, 150),

PointF(0, 200)};

PathGradientBrush pBrush(ptsF, 5);

Color colors[] = {Color(255, 255, 0, 0), // (0, 0) red

Color(255, 0, 255, 0), // (160, 0) green

Color(255, 0, 255, 0), // (160, 200) green

Color(255, 0, 0, 255), // (80, 150) blue

Color(255, 255, 0, 0)}; // (0, 200) red

int count = 5;

Status stat = pBrush.SetSurroundColors(colors, &count);

stat = pBrush.SetCenterColor(Color(255, 255, 255, 255));

stat = graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

Page 57: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 57

GDI+ : Brush

Applying Gamma Correction to a Gradient

SetGammaCorrection 을 이용함 .

LinearGradientBrush brLGradient( Point(0 , 10 ), Point(200, 10),

Color(255,255,0,0) , Color(255,0,0,255));

graphics.FillRectangle( &brLGradient , 0,0,200,50);

graphics.SetGammaCorrection(TRUE);

graphics.FillRectangle( &brLGradient, 0 ,60,200,50);

Page 58: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 58

GDI+ : Brush

Applying Gamma Correction to a Gradient

SetGammaCorrection 을 이용함 .

Point points[] = {Point(75, 0), Point(100, 50), Point(150, 50), Point(112, 75), Point(150, 150),

Point(75, 100), Point(0, 150), Point(37, 75), Point(0, 50), Point(50, 50)};

GraphicsPath path;

path.AddLines(points, 10);

PathGradientBrush pthGrBrush(&path);

pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));

Color colors[] = {Color(255, 0, 0, 0), Color(255, 0, 255, 0), Color(255, 0, 0, 255), Color(255, 255, 255, 255),

Color(255, 0, 0, 0), Color(255, 0, 255, 0), Color(255, 0, 0, 255), Color(255, 255, 255, 255),

Color(255, 0, 0, 0), Color(255, 0, 255, 0)};

int count = 10;

pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillPath(&pthGrBrush, &path);

pthGrBrush.SetGammaCorrection(TRUE);

graphics.TranslateTransform(200.0f, 0.0f);

graphics.FillPath(&pthGrBrush, &path);

Page 59: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 59

GDI+ : Brush

Applying Gamma Correction to a Gradient

SetGammaCorrection 을 이용함 .

Page 60: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 60

GDI+ : Brush

Tiling a Shape with an Image

TextureBrush 를 이용함 .

Image image(L”HouseAndTree.gif”);

TextureBrush brTexture(&image);

Pen penBlack(Color(255,0,0,0));

state = graphics.FillRectangle( &brTexture , Rect( 0,0,200,200));

state = graphics. DrawRectangle( &penBlack , Rect( 0,0,200,200));

Page 61: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 61

GDI+ : Brush

Tiling a Shape with an Image

TextureBrush 를 이용함 .

Image image(L”HouseAndTree.gif”);

TextureBrush brTexture(&image);

Pen penBlack(Color(255,0,0,0));

state = brTexture.SetWrapMode( WarpModeTileFlipX);

state = graphics.FillRectangle( &brTexture , Rect( 0,0,200,200));

state = graphics. DrawRectangle( &penBlack , Rect( 0,0,200,200));

Page 62: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 62

GDI+ : Path

GraphicsPath’s Building Blocks

Lines , Rectangles , Ellipses , Arcs , Polygons

Cardinal Splines , Bzier Splines

GraphicsPath path;

FontFamily fontFamily(L"Times New Roman");

StringFormat stringFormat;

stringFormat.SetLineAlignment(StringAlignmentCenter);

Font font(L“Times New Roman", 20);

SolidBrush solidBrush(Color::Blask);

graphics.DrawString( string1, wcslen(string1), &font, PointF(10, 10), &solidBrush);

path.AddArc(0, 0, 30, 20, -90, 180);

path.AddString(L“a string in a path" , 18 , &fontFamily , 0 , 50 , PointF(20,30) , &stringFormat );

path.AddPie(230, 50, 40,40,40,110);

Pen pen(Color(255,0,0,255), 1);

graphics.DrawPath(&pen, &path);

Page 63: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 63

GDI+ : Path

Filling Open Figures

GraphicsPath path;

path.AddArc(0, 0, 150, 120, 30, 120);

path.AddEllipse(50, 50, 50, 100);

Pen pen(Color(128, 0, 0, 255), 5);

SolidBrush brush(Color(255, 255, 0, 0));

graphics.FillPath(&brush, &path);

graphics.DrawPath(&pen, &path);

Page 64: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 64

GDI+ : Regions

Region Simple : a single rectangle

Complex : a combination of polygons and closed curves

Region Class Intersection

Union

Xor

Exclude

Complement

Page 65: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 65

GDI+ : Regions

Region Class

Complement example

Graphics graphics(hdc);

SolidBrush solidBrush(Color(255, 255, 0, 0));

Point points[] = { Point(110, 20), Point(120, 30), Point(100, 60),

Point(120, 70), Point(150, 60), Point(140, 10)};

Rect rect(65, 15, 70, 45);

GraphicsPath path;

path.AddClosedCurve(points, 6);

Region region(rect);

region.Complement(&path); graphics.FillRegion(&solidBrush, &region);

Page 66: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 66

GDI+ : Regions

Hit Testing with a Region

Region::IsVisible

Point point(60, 10);

SolidBrush solidBrush(Color());

Region region1(Rect(50, 0, 50, 150));

Region region2(Rect(0, 50, 150, 50));

region1.Union(&region2);

if(region1.IsVisible(point, &graphics))

solidBrush.SetColor(Color(255, 255, 0, 0));

else

solidBrush.SetColor(Color(64, 255, 0, 0));

graphics.FillRegion(&solidBrush, &region1);

Page 67: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 67

GDI+ : Regions

Clipping with a Region

Graphics::SetClip 함수와 Region 객체를 이용

Point polyPoints[] = {Point(10, 10), Point(150, 10), Point(100, 75), Point(100, 150)};

GraphicsPath path;

path.AddPolygon(polyPoints, 4);

Region region(&path);

Pen pen(Color(255, 0, 0, 0));

graphics.DrawPath(&pen, &path);

graphics.SetClip(&region);

FontFamily fontFamily(L"Arial");

Font font(&fontFamily, 36, FontStyleBold, UnitPixel);

SolidBrush solidBrush(Color(255, 255, 0, 0));

graphics.DrawString(L"A Clipping Region", 20, &font, PointF(15, 25), &solidBrush);

graphics.DrawString(L"A Clipping Region", 20, &font, PointF(15, 68), &solidBrush);

Page 68: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 68

GDI+ : Image

Image Class

Low Level Image Class

Image image(L“Lena.bmp”);

graphics.DrawImage(&image , 60 , 10 );

Page 69: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 69

GDI+ : Image

Image Class

Meta file

Image image(L“SampleMetaFile.emf”);

graphics.DrawImage(&image , 60 , 10 );

Page 70: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 70

GDI+ : Image

Bitmap Class

High Level Image Class

Bitmap image(L“Lena.bmp”);

graphics.DrawImage(&image , 60 , 10 );

Page 71: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 71

GDI+ : Image

Image Display Code

View Class Member Variable

Bitmap* m_pImage;

View Class Constructor

m_pImage = NULL;

View Class Destructor if( m_pImage != NULL )

Delete m_pImage;

OnDraw

Graphics graphics( pDC->GetSafeHdc() );

graphics.DrawImage(m_pImage , 60 , 10 );

Page 72: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 72

GDI+ : Image

Image Display Code

Image Load Functionbool CImage::SetFileName(CString strImage)

{

m_strImage = strImage;

if( m_pImage != NULL )

{

delete m_pImage;

m_pImage = NULL;

}

int nSizeCount = MultiByteToWideChar( CP_ACP, 0, m_strImage , -1, NULL, 0 );

WCHAR * pWString = new WCHAR[nSizeCount];

MultiByteToWideChar( CP_ACP, 0, m_strImage , -1 , pWString , nSizeCount );

m_pImage = Bitmap::FromFile( pWString );

delete[] pWString;

if( m_pImage == NULL )

return false;

return true;

}

Page 73: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 73

GDI+ : Image

Translation , Rotation , Distortion , Scaling

영상이 출력될 위치점 : 좌상점 , 우상점 , 좌하점

(0,0)

(0,50)

(50,0)

(200,20)

(110,100)

(250,30)

Point destPoints[] = { Point(200,20) , Point(250 , 30) , Point(110, 100) };

Image image(L“Lena.bmp”);

graphics.DrawImage(&image , 0 , 0 );

graphics.DrawImage(&image , destPoints , 3 );

Page 74: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 74

GDI+ : Image

Interpolation Mode to Control Image Quality During Scaling

Graphics::SetInterpolationMode

Graphics::GetInterpolationMode

Interpolation Mode

InterpolationModeNearestNeighbor

InterpolationModeBilinear

InterpolationModeHighQualityBilinear

InterpolationModeBicubic

InterpolationModeHighQualityBicubic

Etc..

Page 75: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 75

GDI+ : Image

Interpolation Mode to Control Image Quality During ScalingImage image(L"GrapeBunch.bmp");

UINT width = image.GetWidth();

UINT height = image.GetHeight();

graphics.DrawImage( &image, Rect(10, 10, width, height), 0, 0, width, height, UnitPixel);

graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);

graphics.DrawImage( &image, Rect(10, 250, 0.6*width, 0.6*height), 0, 0, width, height,

UnitPixel);

graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear);

graphics.DrawImage( &image, Rect(150, 250, 0.6 * width, 0.6 * height), 0, 0, width,

height, UnitPixel);

graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);

graphics.DrawImage( &image, Rect(290, 250, 0.6 * width, 0.6 * height), 0, 0, width,

height, UnitPixel);

Page 76: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 76

GDI+ : Image

Interpolation Mode to Control Image Quality During Scaling

Page 77: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 77

GDI+ : Image

Thumbnail Image

Image image(L“Compass.bmp”);

Image * pThumbnail = image.GetThumbnailImage(100,100,NULL,NULL);

graphics.DrawImage(pThumbnail , 10 , 10 ,

pThumnail->GetWidth() ,

pThumbnail->GetHeight() );

Page 78: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 78

GDI+ : Image

Cached Image

Drawing 속도 향상

Device Independent Image => Display Device dependent Image

Bitmap bitmap(L”Texture.jpg”);

CachedBitmap cbitmap(&bitmap , &graphics );

graphics.DrawImage( &bitmap , 0 , 0 ,

bitmap.GetWidth() ,

bitmap.GetHeight() );

graphics.DrawCachedBitmap(&cBitmap , 0 , 150 );

Page 79: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 79

GDI+ : Image

Improving Performance by Automatic Scaling DrawImage 에 Upper-Left corner 변수만 사용하면 성능이 떨어짐

Graphics.DrawImage( &image, 50 , 30 ); // upper-left cornet at (50, 30)

만약 이미지가 생성된 화면 장치에서의 인치당 픽셀수와 현재 사용되고 있는 화면

장치의 인치당 픽셀수가 다르면 GDI+ 는 현 화면장치에서의 물리적인 이미지의

크기를 이미지가 생성된 화면 장치의 물리적인 크기에 가깝도록 자동으로 크기를

조절한다 .Image image(L”Texture.jpg”);

graphics.DrawImage( &image , 10 , 10 );

graphics.DrawImage( &image , 120 , 10,

image.GetWidth() ,

image.GetHeight() );

Page 80: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 80

GDI+ : Image Codec

Image Codec BMP , JPEG , PNG , TIFF , EMF

Codec : 다른 포맷도 GDI+ 는 지원해준다 .

Codec : MIME type 에 의해 식별됨

Codec’s MIME Type image/bmp

image/gif

image/tiff

image/jpeg

image/emf

image/png

Etc..

Page 81: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 81

GDI+ : Image Codec

Listing Installed Encoders

#include <windows.h>

#include <gdiplus.h>

#include <stdio.h>

using namespace Gdiplus;

INT main() {

GdiplusStartupInput gdiplusStartupInput;

ULONG_PTR gdiplusToken;

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

UINT num; // number of image encoders

UINT size; // size, in bytes, of the image encoder array

ImageCodecInfo* pImageCodecInfo;

GetImageEncodersSize(&num, &size);

Page 82: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 82

GDI+ : Image Codec

Listing Installed EncoderspImageCodecInfo = (ImageCodecInfo*)(malloc(size));

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)

wprintf(L"%s\n", pImageCodecInfo[j].MimeType);

free(pImageCodecInfo);

GdiplusShutdown(gdiplusToken);

return 0;

}

Page 83: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 83

GDI+ : Image Codec

Listing Installed Decoders

#include <windows.h>

#include <gdiplus.h>

#include <stdio.h>

using namespace Gdiplus;

INT main() {

GdiplusStartupInput gdiplusStartupInput;

ULONG_PTR gdiplusToken;

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

UINT num; // number of image encoders

UINT size; // size, in bytes, of the image encoder array

ImageCodecInfo* pImageCodecInfo;

GetImageDecodersSize(&num, &size);

Page 84: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 84

GDI+ : Image Codec

Listing Installed DecoderspImageCodecInfo = (ImageCodecInfo*)(malloc(size));

GetImageDecoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)

wprintf(L"%s\n", pImageCodecInfo[j].MimeType);

free(pImageCodecInfo);

GdiplusShutdown(gdiplusToken);

return 0;

}

Page 85: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 85

GDI+ : Image Codec

int GetCodecClsid( const WCHAR * format , CLSID* pClsid ){

UINT nCodecNum = 0;UINT nCodecInfoSize = 0;

ImageCodecInfo * pImageCodecInfo = NULL; GetImageEncodersSize(&nCodecNum , &nCodecInfoSize );

if( nCodecInfoSize == 0 )return -1;

pImageCodecInfo = (ImageCodecInfo*)new BYTE[nCodecInfoSize];

if( pImageCodecInfo == NULL )return -1;

GetImageEncoders( nCodecNum , nCodecInfoSize , pImageCodecInfo );

Retrieving the Class Identifier for an Encoder

Page 86: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 86

GDI+ : Image Codec

Retrieving the Class Identifier for an Encoderfor( int nIndex = 0 ; nIndex < nCodecNum ; nIndex++ )

{

if( wcscmp(pImageCodecInfo[nIndex].MimeType , format ) == 0 )

{

* pClsid = pImageCodecInfo[nIndex].Clsid;

delete[] pImageCodecInfo;

return nIndex;

}

}

delete[] pImageCodecInfo;

return -1;

}

Page 87: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 87

GDI+ : Image Codec

CLSID clsidCodec;EncoderParameters encoderParams;long lQuality;Status state;

Image image(L"lena.bmp");

if( GetCodecClsid(L"image/jpeg", &clsidCodec ) == -1) return false

encoderParams.Count = 1;encoderParams.Parameter[0].Guid = EncoderQuality;encoderParams.Parameter[0].Type =EncoderParameterValueTypeLong;encoderParams.Parameter[0].NumberOfValues = 1;

lQuality = 100;encoderParams.Parameter[0].Value = &lQuality;state = image.Save(L"lena.jpg", &clsidCodec , &encoderParams );

if( state != OK ) return false;

return true;

Converting a BMP Image to a JPEG Image

Page 88: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 88

GDI+ : Image Codec

#include <windows.h> #include <gdiplus.h> #include <stdio.h> using namespace Gdiplus; INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid);

INT main() {

GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

EncoderParameters encoderParameters; ULONG parameterValue; Status stat;

encoderParameters.Count = 1; encoderParameters.Parameter[0].Guid = EncoderSaveFlag;encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;encoderParameters.Parameter[0].NumberOfValues = 1;encoderParameters.Parameter[0].Value = &parameterValue;

Creating and Saving a Multiple-Frame Image

Page 89: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 89

GDI+ : Image Codec

CLSID encoderClsid;

if( GetEncoderClsid(L"image/tiff", &encoderClsid) == -1 ) return –1;

Image* multi = new Image(L"Shapes.bmp"); Image* page2 = new Image(L"Cereal.gif"); Image* page3 = new Image(L"Iron.jpg"); Image* page4 = new Image(L"House.png");

parameterValue = EncoderValueMultiFrame; stat = multi->Save(L"MultiFrame.tif", &encoderClsid, &encoderParameters); if(stat == Ok) printf("Page 1 saved successfully.\n");

parameterValue = EncoderValueFrameDimensionPage; stat = multi->SaveAdd(page2, &encoderParameters); if(stat == Ok) printf("Page 2 saved successfully.\n");

parameterValue = EncoderValueFrameDimensionPage; stat = multi->SaveAdd(page3, &encoderParameters); if(stat == Ok) printf("Page 3 saved successfully.\n");

Creating and Saving a Multiple-Frame Image

Page 90: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 90

GDI+ : Image Codec

parameterValue = EncoderValueFrameDimensionPage; stat = multi->SaveAdd(page4, &encoderParameters); if(stat == Ok) printf("Page 4 saved successfully.\n");

parameterValue = EncoderValueFlush; stat = multi->SaveAdd(&encoderParameters);

if(stat == Ok) printf("File closed successfully.\n");

delete multi; delete page2; delete page3; delete page4;

GdiplusShutdown(gdiplusToken); return 0;

}

Creating and Saving a Multiple-Frame Image

Page 91: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 91

GDI+ : Graphics Container

Graphics

Vector Image , Raster Image , String format ….

작업을 위한 속성과 디바이스 정보를 유지하는 Container

Graphics State

Device Context

Quality Information

Transformation

Clipping region

Page 92: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 92

GDI+ : Nested Graphics Container

Graphics Container Graphics Object : Container 역할

Graphics State 정보를 유지

BeginContainer , EndContainer

CClientDC dc(this)

Graphics graphics(dc.GetSafeHdc() );Pen pen(Color(255,255,0,0));graphics.TranslateTransform(100,80);

GraphicsContainer graphicContainer = graphics.BeginContainer();graphics.RotateTransform(30);grahpics.DrawRectangle(& pen , -60 , -30 , 120 , 60 );graphics.EndContainer(graphicsContainer);

graphics. DrawRectangle(& pen , -60 , -30 , 120 , 60 );

(100,80)

Page 93: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 93

GDI+ : Alpha Blending

Drawing Opaque and Semitransparent Lines SetCompositingQuality 를 이용하여 Gamma correction 을 적용한

Blending 을 수행할 수 있음 .

Image image(L"Texture1.jpg");

graphics.DrawImage(&image, 10, 5, image.GetWidth(), image.GetHeight());

Pen penOpaque(Color(255, 0, 0, 255), 15);

Pen penSemiTrans( Color(128, 0 , 0, 255), 15);

graphics.DrawLine(&penOpaque, 0, 20, 100, 20 );

graphics.DrawLine(&penSemiTrans, 0, 40, 100, 40 );

graphics.SetCompositingQuality( CompositingQualityGammaCorrected );

graphics.DrawLine(&penSemiTrans, 0, 60, 100, 60 );

Page 94: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 94

GDI+ : Alpha Blending

Color Matrix

Original

Bitmap bitmap(L"Texture1.jpg");

Status stat = graphics.DrawLine(&Pen(Color(255, 0, 0, 0), 25), Point(10, 35), Point(200, 35));

stat = graphics.DrawImage(&bitmap, Rect(30, 0, bitmap.GetWidth(), bitmap.GetHeight()));

Page 95: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 95

GDI+ : Alpha Blending

Color Matrix

Alpha BlendingBitmap bitmap(L"Texture1.jpg"); ColorMatrix colorMatrix = {1, 0, 0, 0, 0,

0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.8, 0 , 0, 0, 0, 0, 1};

ImageAttributes imageAtt;

Status stat = imageAtt.SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

stat = graphics.DrawLine(&Pen(Color(255, 0, 0, 0), 25), Point(10, 35), Point(200, 35));

int iWidth = bitmap.GetWidth();

int iHeight = bitmap.GetHeight();

graphics.DrawImage( &bitmap, Rect(30, 0, iWidth, iHeight), 0.0f, 0.0f, iWidth, iHeight, UnitPixel, &imageAtt );

Page 96: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 96

GDI+ : Alpha Blending

Setting the Alpha Values of Individual PixelINT iWidth = bitmap.GetWidth();

INT iHeight = bitmap.GetHeight();

Color color, colorTemp;

for(INT iRow = 0; iRow < iHeight; iRow++)

{

for(INT iColumn = 0; iColumn < iWidth; iColumn++)

{

bitmap.GetPixel(iColumn, iRow, &color);

colorTemp.SetValue(color.MakeARGB( (BYTE)(255 * iColumn / iWidth),

color.GetRed(), color.GetGreen(), color.GetBlue()));

bitmap.SetPixel(iColumn, iRow, colorTemp);

}

}

Pen pen(Color(255, 0, 0, 0), 25);

graphics.DrawLine(&pen, 10, 35, 200, 35);

graphics.DrawImage(&bitmap, 30, 0, iWidth, iHeight);

Page 97: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 97

GDI+ : Text Antialiasing

Antialiasing with Text SetTextRenderingHint

enum TextRenderingHint

{ TextRenderingHintSystemDefault = 0, TextRenderingHintSingleBitPerPixelGridFit,

TextRenderingHintSingleBitPerPixel, TextRenderingHintAntiAliasGridFit,

TextRenderingHintAntiAlias, TextRenderingHintClearTypeGridFit

};

Page 98: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 98

GDI+ : Text Antialiasing

Antialiasing with Text SetTextRenderingHint

FontFamily fontFamily(L"Times New Roman");

Font font(&fontFamily, 32, FontStyleRegular, UnitPixel);

SolidBrush solidBrush(Color(255, 0, 0, 255));

WCHAR string1[] = L"SingleBitPerPixel";

WCHAR string2[] = L"AntiAlias";

WCHAR string3[] = L"ClearTypeGridFit";

graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel);

graphics.DrawString( string1, wcslen(string1), &font, PointF(10, 10), &solidBrush);

graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);

graphics.DrawString( string2, wcslen(string2), &font, PointF(10, 60), &solidBrush);

graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);

graphics.DrawString( string3, wcslen(string3), &font, PointF(10, 110), &solidBrush);

Page 99: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 99

GDI+ : Antialiasing

Antialiasing with Lines and Curves SetSmoothingMode

enum SmoothingMode

{ SmoothingModeInvalid = QualityModeInvalid,

SmoothingModeDefault = QualityModeDefault,

SmoothingModeHighSpeed = QualityModeLow,

SmoothingModeHighQuality = QualityModeHigh,

SmoothingModeNone,

SmoothingModeAntiAlias

};

myGraphics.SetSmoothingMode(SmoothingModeAntiAlias);

myGraphics.DrawLine(&myPen, 0, 0, 12, 8);

Page 100: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 100

GDI+ : Recoloring

Color Remapping

Colormap Structure 를 이용하여 Old Color => New ColorImage image(L"RemapInput.bmp");

ImageAttributes imageAttributes;

UINT width = image.GetWidth();

UINT height = image.GetHeight();

ColorMap colorMap[1];

colorMap[0].oldColor = Color(255, 255, 0, 0);

colorMap[0].newColor = Color(255, 0, 0, 255);

imageAttributes.SetRemapTable(1, colorMap, ColorAdjustTypeBitmap);

graphics.DrawImage(&image, 10, 10, width, height);

graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height, UnitPixel, &imageAttributes);

Page 101: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 101

GDI+ : Recoloring

Translating Colors ColorMatrix 를 이용해서 해당 Color Component 를 Translating 함

Image image(L"ColorBars.bmp");

ImageAttributes imageAttributes;

UINT width = image.GetWidth();

UINT height = image.GetHeight(); ColorMatrix colorMatrix = { 1, 0, 0, 0, 0,

0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0.75, 0, 0, 0, 1 };

imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

graphics.DrawImage(&image, 10, 10, width, height);

graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height, UnitPixel, &imageAttributes);

Page 102: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 102

GDI+ : Recoloring

Translating Color

Page 103: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 103

GDI+ : Recoloring

Scaling Color ColorMatrix 를 이용해서 해당 Color Component 를 Scaling 함

Image image(L"ColorBars2.bmp");

ImageAttributes imageAttributes;

UINT width = image.GetWidth();

UINT height = image.GetHeight(); ColorMatrix colorMatrix = { 1, 0, 0, 0, 0,

0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1};

imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

graphics.DrawImage(&image, 10, 10, width, height);

graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height, UnitPixel, &imageAttributes);

Page 104: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 104

GDI+ : Recoloring

Scaling Color

Page 105: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 105

GDI+ : Recoloring

Rotating Color Alpha Component 는 1 로 고정시키면

Rotating Color Matrix

Page 106: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 106

GDI+ : Recoloring

Rotating ColorImage image(L"RotationInput.bmp");

ImageAttributes imageAttributes;

UINT width = image.GetWidth();

UINT height = image.GetHeight();

REAL degrees = 60; REAL pi = acos(-1); REAL r = degrees * pi / 180;

ColorMatrix colorMatrix = { cos(r), sin(r), 0.0f, 0.0f, 0.0f,

-sin(r), cos(r), 0.0f, 0.0f, 0.0f,

0.0f, 0.0f, 1.0f, 0.0f, 0.0f,

0.0f, 0.0f, 0.0f, 1.0f, 0.0f,

0.0f, 0.0f, 0.0f, 0.0f, 1.0f };

imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);

graphics.DrawImage(&image, 10, 10, width, height);

graphics.DrawImage( &image, Rect(130, 10, width, height), 0, 0, width, height,

UnitPixel, &imageAttributes);

Page 107: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 107

GDI+ : Recoloring

Rotating Color

Page 108: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 108

GDI+ : Spline

Cardinal Spline

DrawCurve

Point points[] = {Point(0, 100), Point(50, 80), Point(100, 20), Point(150, 80), Point(200, 100)};

Pen pen(Color(255, 0, 0, 255));

graphics.DrawCurve(&pen, points, 5);

Page 109: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 109

GDI+ : Spline

Cardinal Spline

DrawClosedCurve

Point points[] = {Point(60, 60), Point(150, 80), Point(200, 40), Point(180, 120), Point(120, 100), Point(80, 160)};

Pen pen(Color(255, 0, 0, 255)); graphics.DrawClosedCurve(&pen, points, 6);

Page 110: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 110

GDI+ : Spline

Cardinal Spline

Tension

Point points[] = {Point(20, 50), Point(100, 10), Point(200, 100), Point(300, 50), Point(400, 80)};

Pen pen(Color(255, 0, 0, 255)); graphics.DrawCurve(&pen, points, 5, 0.0); // tension 0.0 graphics.DrawCurve(&pen, points, 5, 0.6); // tension 0.6graphics.DrawCurve(&pen, points, 5, 1.0); // tension 1.0

Page 111: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 111

GDI+ : Spline

Bézier Spline

DrawBezier

Point p1(10, 100); // start point Point c1(100, 10); // first control point Point c2(150, 150); // second control point Point p2(200, 100); // end point Pen pen(Color(255, 0, 0, 255)); graphics.DrawBezier(&pen, p1, c1, c2, p2);

Page 112: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 112

GDI+ : Transform

Graphics Transform

Rect rect(0, 0, 50, 50); Pen pen(Color(128, 200, 0, 200), 2); stat = graphics.DrawRectangle(&pen, rect);

stat = graphics.ScaleTransform(1.75, 0.5); stat = graphics.DrawRectangle(&pen, rect);

stat = graphics.ResetTransform(); stat = graphics.RotateTransform(28); stat = graphics.DrawRectangle(&pen, rect);

stat = graphics.ResetTransform(); stat = graphics.TranslateTransform(150, 150); stat = graphics.DrawRectangle(&pen, rect);

Page 113: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 113

GDI+ Example

Bezier Spline Draw Program

Page 114: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 114

GDI+ Example

Bezier Spline Draw Program Bezier Control Point 들을 위한 아이콘 3 개를 추가함 .

Page 115: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 115

GDI+ Example

Bezier Spline Draw Program SDI 형태의 프로젝트를 생성함 .

Page 116: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 116

GDI+ Example

CBezierSpline Class 실제 Bezier Spline 을 그리는 객체

class CBezierSpline{public:

CBezierSpline();CBezierSpline(CPoint ptP1, CPoint ptP2, CPoint ptP3, CPoint ptP4);

virtual ~CBezierSpline();

protected:CPoint m_ptStart;CPoint m_ptEnd;

protected:CPoint m_ptP1;CPoint m_ptP2;CPoint m_ptP3;CPoint m_ptP4;

protected:CPoint* m_pSelectedPoint;

public:CPoint* GetSelectedPoint();

bool PtInControlPoint(CPoint ptPos );public:

CPoint GetP1();void SetP1(CPoint ptP1);

Page 117: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 117

GDI+ Example

Public:CPoint GetP2();void SetP2(CPoint ptP2);

CPoint GetP3();void SetP3(CPoint ptP3);

CPoint GetP4();void SetP4(CPoint ptP4);

public:static CImageList m_imglistPoint;void InitImageList();

public:void ComputeControlPos(double dRate = 0.6);CRect GetBoundBox();

public:virtual void Draw(CDC* pDC , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);virtual void Draw(Graphics* pGraphics , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);

virtual void DrawSpline(CDC * pDC, int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0) , bool bAntialiasing = true);virtual void DrawSpline(Graphics* pGraphics , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);

protected:virtual void DrawControl(CDC * pDC);

public:virtual bool LButtonDown(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);virtual bool LButtonUp(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);

virtual bool MouseMove(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);};

Page 118: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 118

GDI+ Example

#include "stdafx.h"#include "BezierSpline.h"

#include <math.h>

#include "resource.h"

#include "LineEquation.h"

#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif

//---------------------------------------------------------------------------// 함수설명 : Ascending Sorting 을 위한 비교함수 .//---------------------------------------------------------------------------int CompareInt(const void *pLeft, const void *pRight){

int* pL = (int *)pLeft;int* pR = (int *)pRight;

if( *pL > *pR )return 1;

else if( *pL < *pR )return -1;

else return 0;

}

CImageList CBezierSpline::m_imglistPoint;

//--------------------------------------------------------------------------// 함수설명 : 쌍커플을 위한 디폴트 값을 가져야 한다 .//--------------------------------------------------------------------------CBezierSpline::CBezierSpline(){

m_ptP1 = m_ptP4 = CPoint(-1, -1);m_ptP2 = m_ptP3 = CPoint(-1, -1);

//-----------------------------------------------------------------------// 선택된 Control Point 를 가리키는 변수를 초기화한다 .//-----------------------------------------------------------------------m_pSelectedPoint = NULL;

//-----------------------------------------------------------------------// Control Point 를 위한 이미지를 초기화한다 .//-----------------------------------------------------------------------InitImageList();

}

CBezierSpline::CBezierSpline(CPoint ptP1, CPoint ptP2, CPoint ptP3, CPoint ptP4 )

{m_ptP1 = ptP1;m_ptP2 = ptP2;m_ptP3 = ptP3;m_ptP4 = ptP4;

//-----------------------------------------------------------------------// 선택된 Control Point 를 가리키는 변수를 초기화한다 .//-----------------------------------------------------------------------m_pSelectedPoint = NULL;

//-----------------------------------------------------------------------// Control Point 를 위한 이미지를 초기화한다 .//-----------------------------------------------------------------------InitImageList();

}

Page 119: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 119

GDI+ Example

CBezierSpline::~CBezierSpline(){}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline Control Point 를 위한 이미지들을 초기화한다 .//---------------------------------------------------------------------------void CBezierSpline::InitImageList(){

if( !m_imglistPoint.GetSafeHandle() ){

m_imglistPoint.Create(7 , 7 , ILC_COLOR4 | ILC_MASK , 0 , 3 );

m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_FIRST_RECT) );m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_SECOND_RECT) );m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_RECT_TARGET) );

}}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 Start Point 를 지정한다 .//---------------------------------------------------------------------------void CBezierSpline::SetP1(CPoint ptP1){

m_ptP1 = ptP1;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 Start Point 를 반환한다 .//---------------------------------------------------------------------------CPoint CBezierSpline::GetP1(){

return m_ptP1;}

Page 120: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 120

GDI+ Example

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 Start Point 를 반환한다 .//---------------------------------------------------------------------------CPoint CBezierSpline::GetP1(){

return m_ptP1;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 를 지정한다 .//---------------------------------------------------------------------------void CBezierSpline::SetP2(CPoint ptP2){

m_ptP2 = ptP2;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 를 반환한다 .//---------------------------------------------------------------------------CPoint CBezierSpline::GetP2(){

return m_ptP2;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 의 기울기 벡터의 Start// Point 를 지정한다 .//---------------------------------------------------------------------------void CBezierSpline::SetP3(CPoint ptP3){

m_ptP3 = ptP3;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 의 기울기 벡터의 Start // Point 를 반환한다 . //---------------------------------------------------------------------------CPoint CBezierSpline::GetP3(){

return m_ptP3;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 의 기울기 벡터의 End // Point 를 지정한다 .//---------------------------------------------------------------------------void CBezierSpline::SetP4(CPoint ptP4){

m_ptP4 = ptP4;}

//---------------------------------------------------------------------------// 함수설명 : BezierSpline 의 End Point 의 기울기 벡터의 // End Point 를 반환한다 . //---------------------------------------------------------------------------CPoint CBezierSpline::GetP4(){

return m_ptP4;}

Page 121: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 121

GDI+ Example

//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 위한 Control Point 및 라인을 그린다 .//---------------------------------------------------------------------------void CBezierSpline::DrawControl(CDC *pDC){

//-----------------------------------------------------------------------// Start , End Point 와 Control Point 를 연결하는 라인을 그린다 .//-----------------------------------------------------------------------CPen penNew(PS_DOT, 1 , RGB(128,128,128));

CPen * pOldPen = pDC->SelectObject(&penNew);

pDC->MoveTo( m_ptP1 );pDC->LineTo( m_ptP2 );

pDC->MoveTo( m_ptP3 );pDC->LineTo( m_ptP4 );

pDC->SelectObject(pOldPen);

//-----------------------------------------------------------------------// Start , End Point , Control Point 를 위한 Control Point 를 출력한다 .//-----------------------------------------------------------------------//-----------------------------------------------------------------------// 선택되지 않은 상태로 모든 Control Point 들을 출력한다 .//-----------------------------------------------------------------------CPoint ptControl;

ptControl = m_ptP1 - CSize(3,3);m_imglistPoint.Draw( pDC , 0 , ptControl ,

ILD_TRANSPARENT|ILD_NORMAL);

ptControl = m_ptP2 - CSize(3,3);m_imglistPoint.Draw( pDC , 1 , ptControl ,

ILD_TRANSPARENT|ILD_NORMAL);

ptControl = m_ptP3 - CSize(3,3);m_imglistPoint.Draw( pDC , 1 , ptControl ,

ILD_TRANSPARENT|ILD_NORMAL);

ptControl = m_ptP4 - CSize(3,3);m_imglistPoint.Draw( pDC , 0 , ptControl ,

ILD_TRANSPARENT|ILD_NORMAL);

//-----------------------------------------------------------------------// 선택되어져 있는 Control Point 를 출력한다 .//-----------------------------------------------------------------------if( m_pSelectedPoint != NULL ){

ptControl = *m_pSelectedPoint - CSize(3,3);

m_imglistPoint.Draw( pDC , 2 , ptControl , ILD_TRANSPARENT|ILD_NORMAL);

}}

Page 122: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 122

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 그린다 .//---------------------------------------------------------------------------// 변수설명 : nLineWidth : Line 의 굵기// clrLine : Line 의 색상//---------------------------------------------------------------------------void CBezierSpline::Draw(CDC * pDC , int nLineWidth ,

COLORREF clrLine, bool bAntialiasing ){

if( m_ptP1 == CPoint(-1,-1) || m_ptP4 == CPoint(-1,-1) ) return;

//----------------------------------------------------------------------// Control Line 을 그린다 .//----------------------------------------------------------------------DrawControl( pDC );

//----------------------------------------------------------------------// Spline 을 그린다 .//----------------------------------------------------------------------

DrawSpline( pDC , nLineWidth , clrLine , bAntialiasing);}

//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 그린다 .//---------------------------------------------------------------------------// 변수설명 : nLineWidth : Line 의 굵기// clrLine : Line 의 색상//---------------------------------------------------------------------------void CBezierSpline::DrawSpline(CDC * pDC, int nLineWidth ,

COLORREF clrLine, bool bAntialiasing){

Graphics graphics(pDC->GetSafeHdc());DrawSpline( &graphics , nLineWidth , clrLine , bAntialiasing);

}

//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 그린다 .//---------------------------------------------------------------------------// 변수설명 : nLineWidth : Line 의 굵기// clrLine : Line 의 색상//---------------------------------------------------------------------------void CBezierSpline::DrawSpline(Graphics* pGraphics , int nLineWidth ,

COLORREF clrLine, bool bAntialiasing){

Point ptControls[4];ptControls[0].X = m_ptP1.x; ptControls[0].Y = m_ptP1.y;ptControls[1].X = m_ptP2.x; ptControls[1].Y = m_ptP2.y;ptControls[2].X = m_ptP3.x; ptControls[2].Y = m_ptP3.y;ptControls[3].X = m_ptP4.x; ptControls[3].Y = m_ptP4.y;

//-----------------------------------------------------------------------// GDI+ 타입의 Point 배열을 초기화한다 .//-----------------------------------------------------------------------Color colorLine;colorLine.SetFromCOLORREF(clrLine);//-----------------------------------------------------------------------// 지정된 굵기와 색상으로 펜을 생성한다 .//-----------------------------------------------------------------------Pen penNew( colorLine , nLineWidth );//-----------------------------------------------------------------------// Antialiasing 을 지정한다 .//-----------------------------------------------------------------------SmoothingMode modeOld = pGraphics->GetSmoothingMode();

if( bAntialiasing ) pGraphics->SetSmoothingMode(SmoothingModeAntiAlias);

pGraphics->DrawBeziers( &penNew, ptControls , 4 );pGraphics->SetSmoothingMode(modeOld);

}

Page 123: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 123

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : 선택되어 있는 Control Point 의 포인터를 반환한다 .//---------------------------------------------------------------------------CPoint* CBezierSpline::GetSelectedPoint(){

return m_pSelectedPoint;}

//---------------------------------------------------------------------------// 함수설명 : 마우스클릭이 Control Point 를 선택했는지를 체크한다 .//---------------------------------------------------------------------------bool CBezierSpline::PtInControlPoint(CPoint ptPos){

//-----------------------------------------------------------------------// 이전에 선택되어 있는 Control Point 를 해제한다 .//-----------------------------------------------------------------------m_pSelectedPoint = NULL;

//-----------------------------------------------------------------------// 해당 위치의 Control Point 를 찾는다 .//-----------------------------------------------------------------------CRect rcControl = CRect( m_ptP1 - CSize(3,3) , m_ptP1 +

CSize(3,3) );

if( rcControl.PtInRect(ptPos) ){

m_pSelectedPoint = &m_ptP1;return true;

}

rcControl = CRect( m_ptP2 - CSize(3,3) , m_ptP2 + CSize(3,3) );

if( rcControl.PtInRect(ptPos) ){

m_pSelectedPoint = &m_ptP2;return true;

}

rcControl = CRect( m_ptP3 - CSize(3,3) , m_ptP3 + CSize(3,3) );

if( rcControl.PtInRect(ptPos) ){

m_pSelectedPoint = &m_ptP3;return true;

}

rcControl = CRect( m_ptP4 - CSize(3,3) , m_ptP4 + CSize(3,3) );

if( rcControl.PtInRect(ptPos) ){

m_pSelectedPoint = &m_ptP4;return true;

}

return false;}

Page 124: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 124

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : 마우스 왼쪽 버튼을 눌렀을 때 처리한다 .//---------------------------------------------------------------------------// 변수설명 : pWnd : 이 함수를 호출한 윈도우에 대한 포인터 //---------------------------------------------------------------------------// 반환값 : LButtonDown 작업을 수행했는지를 나타낸다 .//---------------------------------------------------------------------------bool CBezierSpline::LButtonDown(CWnd* pWnd , UINT nFlags,

CPoint point, bool bControlMode){

//-----------------------------------------------------------------------// bControlMode == true 이면 Control Point 를 조정하는 모드// 이다 .//-----------------------------------------------------------------------if( bControlMode ){

if( PtInControlPoint(point) ){

pWnd->SetCapture();m_ptStart = m_ptEnd = point;return true;

}}else{

SetP1(point);SetP4(point);

ComputeControlPos();pWnd->SetCapture();return true;

}

return false;}

//---------------------------------------------------------------------------// 함수설명 : 마우스 왼쪽 버튼을 띄었을 때 처리한다 .//---------------------------------------------------------------------------// 변수설명 : pWnd : 이 함수를 호출한 윈도우에 대한 포인터 //---------------------------------------------------------------------------// 반환값 : LButtonUp 작업을 수행했는지를 나타낸다 .//---------------------------------------------------------------------------bool CBezierSpline::LButtonUp(CWnd * pWnd, UINT nFlags,

CPoint point, bool bControlMode){

//-----------------------------------------------------------------------// bControlMode == true 이면 Control Point 를 조정하는 모드이다 .//-----------------------------------------------------------------------if( bControlMode ){ if( m_pSelectedPoint != NULL ) {

if( pWnd == CWnd::GetCapture() ){ *m_pSelectedPoint += (m_ptEnd - m_ptStart);

if( m_ptP1 == *m_pSelectedPoint ) { m_ptP2 += (m_ptEnd - m_ptStart); }

if( m_ptP4 == *m_pSelectedPoint ) { m_ptP3 += (m_ptEnd - m_ptStart); }

ReleaseCapture(); return true;}

}}

Page 125: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 125

GDI+ Exampleelse{ if( pWnd == CWnd::GetCapture() ) {

SetP4(point);ComputeControlPos();

ReleaseCapture();

return true; }}

return false;}

//---------------------------------------------------------------------------// 함수설명 : 마우스 움직일 때를 처리한다 .//---------------------------------------------------------------------------// 변수설명 : pWnd : 이 함수를 호출한 윈도우에 대한 포인터 //---------------------------------------------------------------------------// 반환값 : MouseMove 작업을 수행했는지를 나타낸다 .//---------------------------------------------------------------------------bool CBezierSpline::MouseMove(CWnd * pWnd, UINT nFlags,

CPoint point, bool bControlMode){

//-----------------------------------------------------------------------// bControlMode == true 이면 Control Point 를 조정하는 // 모드이다 .//-----------------------------------------------------------------------if( bControlMode ){ if( m_pSelectedPoint != NULL ) { if( pWnd == CWnd::GetCapture() ) {

m_ptEnd = point;

*m_pSelectedPoint += (m_ptEnd - m_ptStart);

if( m_ptP1 == *m_pSelectedPoint ) { m_ptP2 += (m_ptEnd - m_ptStart); }

if( m_ptP4 == *m_pSelectedPoint ) { m_ptP3 += (m_ptEnd - m_ptStart); }

m_ptStart = m_ptEnd; return true;

} }}else{ if( pWnd == CWnd::GetCapture() ) {

SetP4(point);ComputeControlPos();return true;

}}

return false;}

Page 126: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 126

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 포함하는 사각좌표를 반환한다 .//---------------------------------------------------------------------------CRect CBezierSpline::GetBoundBox(){

int X[4] , Y[4];

X[0] = m_ptP1.x; X[1] = m_ptP2.x; X[2] = m_ptP3.x; X[3] = m_ptP4.x;Y[0] = m_ptP1.y; Y[1] = m_ptP2.y; Y[2] = m_ptP3.y; Y[3] = m_ptP4.y;

qsort(( void*)X , 4 , sizeof(int) , CompareInt);qsort(( void*)Y , 4 , sizeof(int) , CompareInt);

CRect rcBox( X[0] , Y[0] , X[3] , Y[3] );

rcBox.NormalizeRect();rcBox.InflateRect( 10 , 10 , 10 , 10 );

return rcBox;}

//---------------------------------------------------------------------------// 함수설명 : Bezier Spline 을 조정하는 P2 , P3 Control Point 들의 위치를 // 자동으로 계산한다 .//---------------------------------------------------------------------------// 변수설명 : dRate : 삼각형을 이루는 곳까지의 거리의 비율 ..//---------------------------------------------------------------------------void CBezierSpline::ComputeControlPos(double dRate){

//-----------------------------------------------------------------------// P1 , P4 사이의 거리와 둘 사이의 중점을 구한다 .//-----------------------------------------------------------------------CPoint ptCenter;

ptCenter.x = int((m_ptP1.x + m_ptP4.x)/2.0 +0.5);ptCenter.y = int((m_ptP1.y + m_ptP4.y)/2.0 +0.5);

//-----------------------------------------------------------------------// P1 , P4 두점을 지나는 직선 방정식을 구한다 .//-----------------------------------------------------------------------CLineEquation lineA( m_ptP1 , m_ptP4 );

//-----------------------------------------------------------------------// P1 , P4 두점을 지나는 직선에 수직인 직선 방정식을 구한다 .//-----------------------------------------------------------------------CLineEquation lineP;lineP.ComputePerpendicularLine( lineA , ptCenter );

//-----------------------------------------------------------------------// P1 , P4 와 함께 삼각형을 구축하는 점을 계산한다 .//-----------------------------------------------------------------------// P1 , P4 사이의 거리를 구한다 .//-----------------------------------------------------------------------double dLength = sqrt( pow(m_ptP1.x - m_ptP4.x, 2.0)

+ pow(m_ptP1.y - m_ptP4.y , 2.0 ) ) * sqrt(3) / 2.0;

//-----------------------------------------------------------------------// Y 축 값이 작은 것을 선택한다 .//-----------------------------------------------------------------------CPoint * pPoints = lineP.ComputeLengthPoint( ptCenter , dLength );

CPoint ptP5 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];

delete[] pPoints;

Page 127: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 127

GDI+ Example

//-----------------------------------------------------------------------// P1, P5 그리고 P4, P5 를 지나는 각각의 직선방정식을 구한다 .//-----------------------------------------------------------------------CLineEquation lineB( m_ptP1 , ptP5 );CLineEquation lineC( m_ptP4 , ptP5 );

//-----------------------------------------------------------------------// 해당 거리에 있는 Y 축 값이 작은 위치를 P2 , P3 로 지정한다 .//-----------------------------------------------------------------------pPoints = lineB.ComputeLengthPoint( m_ptP1 , dLength*dRate );

m_ptP2 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];

delete[] pPoints;

pPoints = lineC.ComputeLengthPoint( m_ptP4 , dLength*dRate );

m_ptP3 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];

delete[] pPoints;}

Page 128: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 128

GDI+ Example

CLineEquation Class Bezier Spline 에서 이용되는 라인 함수들을 관리한다 .

class CLineEquation{public:

CLineEquation(); CLineEquation(CPoint ptP1 , CPoint ptP2); CLineEquation(double dSlop , CPoint ptP);

virtual ~CLineEquation();

private:double m_dA;double m_dB;double m_dC;

public:void SetA(double dA);void SetB(double dB);void SetC(double dC);

double GetA();double GetB();double GetC();

public:void ComputeLineEquation( CPoint ptP1 , CPoint ptP2 );void ComputeLineEquation( double dSlop , CPoint ptP );

public:void ComputePerpendicularLine( CLineEquation& lineA , CPoint ptP);void ComputeDivideLine( CLineEquation lineA, CLineEquation lineB);

CPoint* ComputeLengthPoint(CPoint ptPos , double dLength);

public:static CPoint ComputeCrossPoint(CLineEquation& lineA , CLineEquation lineB);

public:CPoint GetXPos( int nY);CPoint GetYPos( int nX);

};

Page 129: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 129

GDI+ ExampleCLineEquation::CLineEquation(){

m_dA = m_dB = m_dC = 0;}

//--------------------------------------------------------------------------// 함수설명 : 두 점을 지나는 직선 방정식을 지정한다 .//--------------------------------------------------------------------------// 변수설명 : ptP1 , ptP2 : 하나의 직선이 자나는 두점을 나타냄//--------------------------------------------------------------------------CLineEquation::CLineEquation(CPoint ptP1 , CPoint ptP2){

ComputeLineEquation(ptP1 , ptP2);}

//--------------------------------------------------------------------------// 함수설명 : 기울기와 한점을 지자는 직선 방정식을 지정한다 . //--------------------------------------------------------------------------// 변수설명 : dSlop : 기울기 ptP : 직선위의 임의의 점//--------------------------------------------------------------------------CLineEquation::CLineEquation(double dSlop , CPoint ptP){

ComputeLineEquation(dSlop , ptP);}

CLineEquation::~CLineEquation(){}

//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 a 를 반환함//---------------------------------------------------------------------------double CLineEquation::GetA(){

return m_dA;}

//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 b 를 반환함//---------------------------------------------------------------------------double CLineEquation::GetB(){

return m_dB;}//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 c 를 반환함//---------------------------------------------------------------------------double CLineEquation::GetC(){

return m_dC;}//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 a 를 지정함//---------------------------------------------------------------------------void CLineEquation::SetA(double dA){

m_dA = dA;}//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 b 를 지정함//---------------------------------------------------------------------------void CLineEquation::SetB(double dB){

m_dB = dB;}//---------------------------------------------------------------------------// 함수설명 : 직선의 방정식 ax + by + c = 0 에서 c 를 지정함//---------------------------------------------------------------------------void CLineEquation::SetC(double dC){

m_dC = dC;}

Page 130: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 130

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : 두점을 지나는 직선의 방정식을 구한다 .//---------------------------------------------------------------------------// 변수설명 : ptP1 , ptP2 : 직선이 지나는 두점을 나타냄//---------------------------------------------------------------------------// 부가설명 : (y1-y2)x + (x2-x1)y + x1y2 - x2y1 = 0//---------------------------------------------------------------------------void CLineEquation::ComputeLineEquation(CPoint ptP1, CPoint ptP2){

m_dA = ptP1.y - ptP2.y;m_dB = ptP2.x - ptP1.x;m_dC = ptP1.x*ptP2.y - ptP2.x*ptP1.y;

double dNorm = sqrt(m_dA*m_dA + m_dB*m_dB);

m_dA /= dNorm;m_dB /= dNorm;m_dC /= dNorm;

}

//---------------------------------------------------------------------------// 함수설명 : 직선의 기울기와 직선이 지나는 점을 이용해서 직선의// 방정식을 구한다 .//---------------------------------------------------------------------------// 변수설명 : dSlop : 기울기// ptP : 직선이 지나는 하나의 점//---------------------------------------------------------------------------// 부가설명 : -mx + y - b = 0 을 놓고서 b 를 결정하면 된다 .//---------------------------------------------------------------------------void CLineEquation::ComputeLineEquation(double dSlop, CPoint ptP){

m_dA = -dSlop;m_dB = 1;

m_dC = -dSlop* ptP.x + ptP.y;}

//---------------------------------------------------------------------------// 함수설명 : 두 직선의 교점을 구한다 .//---------------------------------------------------------------------------// 부가설명 : 첫번째 직선 : ax + by + c = 0// 두번째 직선 : dx + ey + f = 0//---------------------------------------------------------------------------CPoint CLineEquation::ComputeCrossPoint(CLineEquation &lineA,

CLineEquation lineB){

CPoint ptCross;

double a = lineA.GetA() , b = lineA.GetB() , c = lineA.GetC();double d = lineB.GetA() , e = lineB.GetB() , f = lineB.GetC();

if( (( d*b - a*e ) == 0.0 ) || ( a == 0.0 && d == 0.0 ) || ( b == 0.0 && e == 0.0 )){

return CPoint(-1,-1);}//-----------------------------------------------------------------------// a 와 d 또는 b 와 e 가 동시에 0 이 될 수 없다 .//-----------------------------------------------------------------------if( a == 0 ){

ptCross.y = -1 * c / b;ptCross.x = (-1*e*ptCross.y - f)/d;

return ptCross;

}else if( b == 0 ){

ptCross.x = -1 * c / a;ptCross.y = (-1*d*ptCross.x - f)/e;

return ptCross;}

Page 131: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 131

GDI+ Example

if( d == 0 ){

ptCross.y = -1 * f / e; ptCross.x = (-1*b*ptCross.y - c)/a;

return ptCross;

}else if( e == 0 ){

ptCross.x = -1 * f / d; ptCross.y = (-1*a*ptCross.x - c)/b;

return ptCross;}

//-----------------------------------------------------------------------// a,b,c,d,e,f 들 중 0 인 것이 하나도 없을 때//-----------------------------------------------------------------------ptCross.x = ( e*c - b*f ) / ( d*b - a*e ); ptCross.y = ( -1*a*ptCross.x - c )/b;

return ptCross;}

//---------------------------------------------------------------------------// 함수설명 : 두 라인이 이루는 각을 이등분 하는 직선을 구한다 .//---------------------------------------------------------------------------// 부가설명 : 첫번째 직선 : ax + by + c = 0// 두번째 직선 : dx + ey + f = 0//---------------------------------------------------------------------------void CLineEquation::ComputeDivideLine(CLineEquation lineA,

CLineEquation lineB){}

//---------------------------------------------------------------------------// 함수설명 : 한 라인에 수직이면서 한점을 지나는 직선 방정식을 구한다 .//---------------------------------------------------------------------------// 변수설명 : lineA : 기준이 되는 직선 방정식// ptP : 수직인 직선 방정식이 지나는 점을 나타낸다 .//---------------------------------------------------------------------------void CLineEquation::ComputePerpendicularLine(CLineEquation &lineA, CPoint ptP){

//-----------------------------------------------------------------------// 직선방정식 lineA 의 방향 벡터를 얻는다 .//-----------------------------------------------------------------------double l = lineA.GetB();double m = -lineA.GetA();

//-----------------------------------------------------------------------// 직선과 수직인 직선의 방향벡터를 구한다 .//-----------------------------------------------------------------------double vl = -1*m;double vm = l;

//-----------------------------------------------------------------------// 직선의 방향벡터와 그 직선이 지나는 점을 이용해서

// 직선방정식을 구한다 .//-----------------------------------------------------------------------m_dA = vm;m_dB = -vl;m_dC = -vm*ptP.x + vl*ptP.y;

}

Page 132: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 132

GDI+ Example//---------------------------------------------------------------------------// 함수설명 : 라인위의 한점을 반환한다 .//---------------------------------------------------------------------------// 변수설명 : nX : X 축 좌표 ..//---------------------------------------------------------------------------CPoint CLineEquation::GetYPos(int nX){

//-----------------------------------------------------------------------// 직선이 Y 축에 수평이라는 것을 나타낸다 .//-----------------------------------------------------------------------if( m_dB == 0 ) return CPoint( int(-1*m_dC/m_dA) , 0 );

int nY = (int)( -1*(m_dC + m_dA*nX)/m_dB );

return CPoint( nX , nY );}

//---------------------------------------------------------------------------// 함수설명 : 라인위의 한점을 반환한다 .//---------------------------------------------------------------------------// 변수설명 : nY : Y 축 좌표 ..//---------------------------------------------------------------------------CPoint CLineEquation::GetXPos(int nY){

//-----------------------------------------------------------------------// 직선이 x 축에 수평이라는 것을 나타낸다 .//-----------------------------------------------------------------------if( m_dA == 0 ) return CPoint( int(-1*m_dC/m_dB) , 0 );

int nX = (int)( -1*(m_dC + m_dB*nY)/m_dA );

return CPoint( nX , nY );}

//---------------------------------------------------------------------------// 함수설명 : 라인위의 한점에서 지정된 거리에 있는 점을 찾는다 .//---------------------------------------------------------------------------// 변수설명 : ptPos : 거리측정을 하기 위한 라인위의 한점 .. (x1, y1 을 의미함 )// nLength : 기준점에서부터의 거리를 나타냄//---------------------------------------------------------------------------// 부가설명 : dx + ey + f = 0 임의의 점 ( m , n ) 을 대입하고 정리하면 // 1....... n = -d/e*m - f/e// 2....... (x1-m)^2 + (y1-n)^2 = L^2// 3....... am^2 + bm + c = 0 에서 m 의 근을 구한다 .//// k = d/e l = f/e + y1// a = 1+k^2 b = 2(kl - x1) c = l^2 - L^2//---------------------------------------------------------------------------// 부가설명 : 이함수를 호출하는 곳에서는 반드시 메모리를 해제해야 // 한다 .//---------------------------------------------------------------------------CPoint* CLineEquation::ComputeLengthPoint(CPoint ptPos, double dLength){

CPoint * pPoints = new CPoint[2];

//-----------------------------------------------------------------------// x 축에 수평인 직선을 나타낸다 .//-----------------------------------------------------------------------if( m_dA == 0 ){

pPoints[0].y = pPoints[1].y = ptPos.y;

pPoints[0].x = int(ptPos.x + dLength);pPoints[1].x = int(ptPos.x - dLength);

return pPoints;}

Page 133: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 133

GDI+ Example//-----------------------------------------------------------------------// y 축에 수평인 직선을 나타낸다 .//-----------------------------------------------------------------------if( m_dB == 0 ){

pPoints[0].x = pPoints[1].x = ptPos.x;

pPoints[0].y = int(ptPos.y + dLength);pPoints[1].y = int(ptPos.y - dLength);

return pPoints;}

//-----------------------------------------------------------------------// 공식에 넣어서 .. 계산을 한다 . 직선의 방정식을 dx + ey + f = 0 로 정의//-----------------------------------------------------------------------double k = m_dA/m_dB;double l = m_dC/m_dB + ptPos.y;

double a = 1+k*k;double b = 2*(k*l - ptPos.x);double c = ptPos.x*ptPos.x + l*l - dLength*dLength;

//-----------------------------------------------------------------------// 근의 공식을 이용해서 두개의 근을 구한다 .//-----------------------------------------------------------------------double dX = (-1*b+sqrt(b*b - 4*a*c))/(2.0*a);pPoints[0].x = (int)( dX );pPoints[0].y = (int)( -1*(m_dC + m_dA*dX)/m_dB );

dX = (-1*b-sqrt(b*b - 4*a*c))/(2.0*a);pPoints[1].x = (int)( dX );pPoints[1].y = (int)( -1*(m_dC + m_dA*dX)/m_dB );

return pPoints;}

Page 134: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 134

GDI+ Example

CBezierView Class Bezier Spline 관리하는 View 객체

void CBezierView::OnDraw(CDC* pDC){

CBezierDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data here

//----------------------------------------------------------------------// Cliping 영역의 크기를 얻어온다 .//----------------------------------------------------------------------CRect rcClipBox;pDC->GetClipBox(rcClipBox);

Draw( pDC , rcClipBox );}

void CBezierView::OnLButtonDown(UINT nFlags, CPoint point) {

bool bResult;

CRect rcOldBoundBox = m_splineBezier.GetBoundBox();

if( m_nMode == ID_BEZIER_SPLINE_DRAW ){

bResult = m_splineBezier.LButtonDown( this , nFlags , point );

}

else{

bResult = m_splineBezier.LButtonDown( this , nFlags ,

point , true );}

if( bResult ){

//--------------------------------------------------------------// 새롭게 지정된 Spline 만 그리도록 한다 .

//--------------------------------------------------------------CClientDC dc(this);

CRect rcClipBox;rcClipBox.UnionRect( rcOldBoundBox ,

m_splineBezier.GetBoundBox() );

Draw( &dc , rcClipBox );}

CView::OnLButtonDown(nFlags, point);}

Page 135: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 135

GDI+ Examplevoid CBezierView::OnMouseMove(UINT nFlags, CPoint point) {

bool bResult;

CRect rcOldBoundBox = m_splineBezier.GetBoundBox();

if( m_nMode == ID_BEZIER_SPLINE_DRAW ){

bResult = m_splineBezier.MouseMove( this , nFlags , point );

}else{

bResult = m_splineBezier.MouseMove( this , nFlags , point , true );

}

if( bResult ){

//--------------------------------------------------------------// 새롭게 지정된 Spline 만 그리도록 한다 .

//--------------------------------------------------------------CClientDC dc(this);

CRect rcClipBox;rcClipBox.UnionRect( rcOldBoundBox , m_splineBezier.GetBoundBox() );

Draw( &dc , rcClipBox );}

CView::OnMouseMove(nFlags, point);}

void CBezierView::OnLButtonUp(UINT nFlags, CPoint point) {

bool bResult;

CRect rcOldBoundBox = m_splineBezier.GetBoundBox();

if( m_nMode == ID_BEZIER_SPLINE_DRAW ){

bResult = m_splineBezier.LButtonUp( this , nFlags , point );

}else{

bResult = m_splineBezier.LButtonUp( this , nFlags , point , true );

}

if( bResult ){

//--------------------------------------------------------------// 새롭게 지정된 Spline 만 그리도록 한다 .//--------------------------------------------------------------CClientDC dc(this);

CRect rcClipBox;rcClipBox.UnionRect( rcOldBoundBox , m_splineBezier.GetBoundBox() );

Draw( &dc , rcClipBox );}

CView::OnLButtonUp(nFlags, point);}

Page 136: Win32 API System Programming

한양대학교 컴퓨터공학과 컴퓨터 비젼 & 패턴인식 연구실 박현 136

GDI+ Examplevoid CBezierView::OnBezierSplineDraw() {

m_nMode = ID_BEZIER_SPLINE_DRAW;}

void CBezierView::OnUpdateBezierSplineDraw(CCmdUI* pCmdUI) {

pCmdUI->SetCheck( m_nMode == ID_BEZIER_SPLINE_DRAW );

}

void CBezierView::OnBezierSplineControl() {

m_nMode = ID_BEZIER_SPLINE_CONTROL;}

void CBezierView::OnUpdateBezierSplineControl(CCmdUI* pCmdUI) {

pCmdUI->SetCheck( m_nMode == ID_BEZIER_SPLINE_CONTROL );

}

void CBezierView::Draw(CDC *pDC, CRect rcClipBox){

//----------------------------------------------------------------------// 윈도우의 크기를 얻어온다 .//----------------------------------------------------------------------CRect rcClient;GetClientRect( rcClient );

//----------------------------------------------------------------------// 깜박거림을 제거하기 위해서 Memory Device Context 를 사용한다 .//----------------------------------------------------------------------CDC dcMem;dcMem.CreateCompatibleDC(pDC);

CBitmap bmMem;bmMem.CreateCompatibleBitmap(pDC, rcClient.Width() ,

rcClient.Height() );

CBitmap* pOldBitmap = (CBitmap *)dcMem.SelectObject(&bmMem);

dcMem.FillRect( rcClient , &CBrush(RGB(255,255,255)));

//---------------------------------------------------------------------// Bezier Spline 을 Memory DC 에 그린다 .//---------------------------------------------------------------------m_splineBezier.Draw( &dcMem );

pDC->StretchBlt( rcClipBox.left, rcClipBox.top , rcClipBox.Width() , rcClipBox.Height() , &dcMem , rcClipBox.left, rcClipBox.top , rcClipBox.Width() , rcClipBox.Height() , SRCCOPY );

dcMem.SelectObject( pOldBitmap );}