Professional Documents
Culture Documents
Contents
GDI
Device Context
GDI+
GDI
GDI ( Graphic Device Interface )
Window OS
Application
GDI
Virtual
Device
Driver
Graphic
Hardware
GDI Object
GDI Object
GDI
GDI
Device Context
Text
Mapping mode
GDI
GDI Parameter .
: + +
Device Context
DC
Simple Method
CDC * pDC = GetDC();
// Drawing
ReleaseDC( pDC );
OnPaint Handler
PAINTSTRUCT ps;
CDC * pDC = BeginPaint( &ps );
//Drawing
EndPaint( &ps );
DC
DC
PAINTSTRUCT ps;
CDC * pDC = BeginPaint( &ps );
//Drawing
EndPaint ???
CPaintDC
OnPaint
CWnd::BeginPaint() ~ CWnd::EndPaint();
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()
Drawing Function
CDC Draw Function
Function
Description
LineTo
Current Position .
Rectangle
RoundRect
Ellipse
Pie
Polygon
PolyBezier
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
10
Mapping Mode
Logical Coordinate
MoveTo , LineTo :
Device Context
CDC::SetWindowOrg
Device Coordinate
GDI : ,
(Device Coordinate)
CDC::SetViewPortOrg
(0,0)
11
Mapping Mode
CDC::SetViewPortOrg
(0,0)
(0,0) Logical Coordinate Origin
(x,y) Device Unit
CDC::SetWindowOrg
(0,0)
(0,0)
(x,y) Logical coordinate
(x,y) Logical coordinate
12
Mapping Mode
CDC::SetMapMode
13
GDI+
GDI+
GDI+
2D Vector Graphics
Image processing
Typography
14
GDI+
GDI+
2D Vector Graphics
Drawing Primitives
Image processing
Image ( CachedBitmap )
Typography
, , TEXT
Font Antialiasing
15
GDI+
GDI+
Gradient Brushes
Cardinal Splines
Scalable Regions
Alpha Blending
Antialiasing
Etc..
16
GDI+
Gradient Brushes
17
GDI+
Cardinal Splines
GDI
DC Path
GDI+
Graphics Path
Path .
18
GDI+
Transformation & Matrix Object
Matrix Object
19
GDI+
Scalable Region
GDI
Device Coordinate
Translation
GDI+
World coordinate ( )
20
GDI+
Alpha Blending
Transparency
Antialiasing
21
GDI+
Recoloring
22
GDI+
Graphics Container
Graphics State
Outer
Container
Inner Container
Antialiasing mode
23
GDI+
Various Image format
BMP
GIF
JEPG
Exif
PNG
TIFF
ICON
WMF
EMF
24
SelectObject Function .
Current Position
Brush
Resion Path
GDI+
Graphics
Overloading
Current Position
Region Path
25
StdAfx.h
#ifndef ULONG_PTR
#endif
#include <Gdiplus.h>
#include <GdiplusBase.h>
#include <GdiplusColor.h>
#include <GdiplusPen.h>
#include <GdiplusBrush.h>
#include <GdiplusPath.h>
#include <Gdiplusgraphics.h>
26
CWinApp
Member Variable
ULONG_PTR m_gdiplusToken;
InitInstance()
GdiplusStartupInput gdiplusStartupInput;
// Initialize GDI+
ExitInstance()
GdiplusShutdown(m_gdiplusToken);
27
World Coordinate
Page Coordinate
Device Coordinate
28
Transform .
(0,0) . ( )
(0,0) . ( )
29
( 100 , 50 )
30
World Transformation
Graphics .
World Coordinate
Page Coordinate
World Transformmation
TranslateTransform .
31
Page Transformation
Graphics .
Page Coordinate
Device Coordinate
Page Transformmation
graphics.SetPageUnit( UnitInch );
graphics.DrawLine( &myPen , 0 , 0 , 2, 1);
32
Page Transformation
33
34
Clone, Equals .
Geometric Transformations
cos
sin
sin
cos
0
Rotate
0
1
x scale
y scale 0
0
1
x translate
Scale
0
0
1
0
y translate 1
Translate
35
36
MultiplyTransform , RotateTransform ,
ScaleTransform , TranslateTransform
37
GDI+ : Pen
Pen
38
GDI+ : Pen
Pen
39
GDI+ : Pen
Pen
40
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
41
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 );
42
GDI+ : Pen
Pen
LineCapCustom
Class CustomLineCap
GraphicsPath .
fillPath strokePath .
43
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));
44
GDI+ : Pen
Pen
LineCapCustom
Class CustomLineCap
Based Vertical Line
LineCapTriangle
LineCapRound
-15
45
GDI+ : Pen
Pen
LineCapCustom
CustomLineCap
BaseClass
AdjustableArrowCap
SubClass
Class AdjustableArrowCap
.
width
height
46
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));
47
GDI+ : Pen
Pen
Dash Line
48
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);
49
GDI+ : Pen
Pen
Texture Image .
Status state;
Image image(LTexture.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);
50
GDI+ : Brush
Brush
SolidBrush brSolid(Color(255,255,0,0));
Status state = graphics.FillEllipse( &brSolid , 0 , 0 , 100 , 50 );
51
GDI+ : Brush
Brush
Hatch Style
52
GDI+ : Brush
Gradient Brush
LinearGradientBrush
53
GDI+ : Brush
Gradient Brush
LinearGradientBrush
54
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 );
55
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));
56
GDI+ : Brush
Applying Gamma Correction to a Gradient
SetGammaCorrection .
57
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);
58
GDI+ : Brush
Applying Gamma Correction to a Gradient
SetGammaCorrection .
59
GDI+ : Brush
Tiling a Shape with an Image
TextureBrush .
Image image(LHouseAndTree.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));
60
GDI+ : Brush
Tiling a Shape with an Image
TextureBrush .
Image image(LHouseAndTree.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));
61
GDI+ : Path
GraphicsPaths Building Blocks
62
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);
63
GDI+ : Regions
Region
Region Class
Intersection
Union
Xor
Exclude
Complement
64
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, ®ion);
65
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(®ion2);
if(region1.IsVisible(point, &graphics))
solidBrush.SetColor(Color(255, 255, 0, 0));
else
solidBrush.SetColor(Color(64, 255, 0, 0));
graphics.FillRegion(&solidBrush, ®ion1);
66
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(®ion);
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);
67
GDI+ : Image
Image Class
68
GDI+ : Image
Image Class
Meta file
Image image(LSampleMetaFile.emf);
graphics.DrawImage(&image , 60 , 10 );
69
GDI+ : Image
Bitmap Class
70
GDI+ : Image
Image Display Code
m_pImage = NULL;
Bitmap* m_pImage;
OnDraw
graphics.DrawImage(m_pImage , 60 , 10 );
71
GDI+ : Image
Image Display Code
72
GDI+ : Image
Translation , Rotation , Distortion , Scaling
: , ,
(0,0)
(50,0)
(200,20)
(250,30)
(0,50
)
(110,100
)
73
GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling
Graphics::SetInterpolationMode
Graphics::GetInterpolationMode
Interpolation Mode
InterpolationModeNearestNeighbor
InterpolationModeBilinear
InterpolationModeHighQualityBilinear
InterpolationModeBicubic
InterpolationModeHighQualityBicubic
Etc..
74
GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling
Image 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);
75
GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling
76
GDI+ : Image
Thumbnail Image
Image image(LCompass.bmp);
Image * pThumbnail = image.GetThumbnailImage(100,100,NULL,NULL);
graphics.DrawImage(pThumbnail , 10 , 10 ,
pThumnail->GetWidth() ,
pThumbnail->GetHeight() );
77
GDI+ : Image
Cached Image
Drawing
Bitmap bitmap(LTexture.jpg);
CachedBitmap cbitmap(&bitmap , &graphics );
graphics.DrawImage( &bitmap , 0 , 0 ,
bitmap.GetWidth() ,
bitmap.GetHeight() );
graphics.DrawCachedBitmap(&cBitmap , 0 , 150 );
78
GDI+ : Image
Improving Performance by Automatic Scaling
GDI+
.
Image image(LTexture.jpg);
graphics.DrawImage( &image , 10 , 10 );
graphics.DrawImage( &image , 120 , 10,
image.GetWidth() ,
image.GetHeight() );
79
Codec : GDI+ .
image/bmp
image/gif
image/tiff
image/jpeg
image/emf
image/png
Etc..
80
81
82
83
84
85
86
clsidCodec;
encoderParams;
lQuality;
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;
87
88
89
90
Container
Graphics State
Device Context
Quality Information
Transformation
Clipping region
91
Graphics State
BeginContainer , EndContainer
CClientDC dc(this)
Graphics
graphics(dc.GetSafeHdc() );
Pen
pen(Color(255,255,0,0));
graphics.TranslateTransform(100,80);
(100,80)
92
93
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()));
94
Alpha Blending
Bitmap 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 );
95
96
SetTextRenderingHint
enum TextRenderingHint
{
TextRenderingHintSystemDefault = 0,
TextRenderingHintSingleBitPerPixelGridFit,
TextRenderingHintSingleBitPerPixel,
TextRenderingHintAntiAliasGridFit,
TextRenderingHintAntiAlias,
TextRenderingHintClearTypeGridFit
};
97
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);
98
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);
99
GDI+ : Recoloring
Color Remapping
100
GDI+ : Recoloring
Translating Colors
101
GDI+ : Recoloring
Translating Color
102
GDI+ : Recoloring
Scaling Color
103
GDI+ : Recoloring
Scaling Color
104
GDI+ : Recoloring
Rotating Color
Alpha Component 1
105
GDI+ : Recoloring
Rotating Color
Image image(L"RotationInput.bmp");
ImageAttributes imageAttributes;
UINT width = image.GetWidth();
UINT height = image.GetHeight();
REAL degrees = 60;
REAL pi = acos(-1);
106
GDI+ : Recoloring
Rotating Color
107
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);
108
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);
109
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.6
graphics.DrawCurve(&pen, points, 5, 1.0); // tension 1.0
110
GDI+ : Spline
Bzier 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);
111
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);
112
GDI+ Example
Bezier Spline Draw Program
113
GDI+ Example
Bezier Spline Draw Program
114
GDI+ Example
Bezier Spline Draw Program
SDI .
115
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);
116
GDI+ Example
Public:
CPoint GetP2();
void SetP2(CPoint ptP2);
CPoint GetP3();
void SetP3(CPoint ptP3);
CPoint GetP4();
void SetP4(CPoint ptP4);
public:
static CImageList
void InitImageList();
m_imglistPoint;
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);
117
GDI+ Example
#include "stdafx.h"
#include "BezierSpline.h"
#include <math.h>
#include "resource.h"
//-------------------------------------------------------------------------// : .
//-------------------------------------------------------------------------CBezierSpline::CBezierSpline()
{
m_ptP1 = m_ptP4 = CPoint(-1, -1);
m_ptP2 = m_ptP3 = CPoint(-1, -1);
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------m_pSelectedPoint = NULL;
#include "LineEquation.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//--------------------------------------------------------------------------// : Ascending Sorting .
//--------------------------------------------------------------------------int CompareInt(const void *pLeft, const void *pRight)
{
int* pL = (int *)pLeft;
int* pR = (int *)pRight;
CImageList CBezierSpline::m_imglistPoint;
118
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) );
119
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;
}
120
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));
121
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);
if( bAntialiasing )
pGraphics->SetSmoothingMode(SmoothingModeAntiAlias);
122
GDI+ Example
//--------------------------------------------------------------------------// : Control Point .
//--------------------------------------------------------------------------CPoint* CBezierSpline::GetSelectedPoint()
{
return m_pSelectedPoint;
}
//--------------------------------------------------------------------------//
: Control Point
.
if( rcControl.PtInRect(ptPos) )
{
m_pSelectedPoint = &m_ptP4;
return true;
}
}
return false;
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;
}
123
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);
}
}
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : 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);
}
ComputeControlPos();
pWnd->SetCapture();
return true;
ReleaseCapture();
return true;
return false;
}
124
GDI+ Example
else
{
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_ptStart = m_ptEnd;
return true;
}
else
{
}
}
return false;
125
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;
126
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;
127
GDI+ Example
CLineEquation Class
Bezier Spline .
class CLineEquation
{
public:
CLineEquation();
CLineEquation(CPoint ptP1 , CPoint ptP2);
CLineEquation(double dSlop , CPoint ptP);
virtual ~CLineEquation();
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);
private:
double m_dA;
double m_dB;
double m_dC;
public:
static CPoint ComputeCrossPoint(CLineEquation& lineA , CLineEquation lineB);
public:
void SetA(double dA);
void SetB(double dB);
void SetC(double dC);
public:
CPoint GetXPos( int nY);
CPoint GetYPos( int nX);
};
double GetA();
double GetB();
double GetC();
128
GDI+ Example
CLineEquation::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;
}
129
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;
}
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : : 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;
130
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;
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : 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;
//----------------------------------------------------------------------// 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)
{
}
//----------------------------------------------------------------------//
// .
//----------------------------------------------------------------------m_dA = vm;
m_dB = -vl;
m_dC = -vm*ptP.x + vl*ptP.y;
131
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 );
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : 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 CPoint( nX , nY );
return pPoints;
}
132
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;
133
GDI+ Example
CBezierView Class
else
{
//---------------------------------------------------------------------// Cliping .
//---------------------------------------------------------------------CRect rcClipBox;
pDC->GetClipBox(rcClipBox);
}
if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);
CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );
bResult =
m_splineBezier.LButtonDown( this , nFlags ,
point , true );
CView::OnLButtonDown(nFlags, point);
}
134
GDI+ Example
void CBezierView::OnMouseMove(UINT nFlags, CPoint point)
{
bool bResult;
CRect rcOldBoundBox = m_splineBezier.GetBoundBox();
if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);
if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);
CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );
CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );
}
}
CView::OnMouseMove(nFlags, point);
}
}
CView::OnLButtonUp(nFlags, point);
135
GDI+ Example
void 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;
}
CBitmap bmMem;
bmMem.CreateCompatibleBitmap(pDC, rcClient.Width() ,
rcClient.Height() );
136