Properties · Methods · Examples
Declaration
TIECanvas = class;
Description
TIECanvas is a wrapper for GDI+ and TCanvas, and supports anti-aliasing, alpha merging, and advanced drawing methods.
It is available via
TIEBitmap.IECanvas or by creating it from a TBitmap or TCanvas.
General
Draw Methods
Fill Methods
Text Methods
Advanced Draw Methods
Transformation Methods
// Fill image with a vertical gradient from yellow to red
ImageEnView1.IEBitmap.IECanvas.GradientFillRect( Rect( 0, 0, ImageEnView1.IEBitmap.Width, ImageEnView1.IEBitmap.Height ), clYellow, clRed, gpgVertical );
ImageEnView1.Update();
// Draw an envelope with 50% transparency
with ImageEnView1.IEBitmap.IECanvas do
begin
Pen.Mode := pmCopy;
Pen.Style := psSolid;
Pen.Color := clBlack;
Pen.Transparency := 128;
Brush.Color := clYellow;
Brush.Style := bsSolid;
Brush.Transparency := 128;
// Draw outer rect
Rectangle( 100, 100, 500, 300 );
// Draw flap
MoveTo( 100, 100 );
LineTo( 300, 200 );
LineTo( 500, 100 );
end;
ImageEnView1.Update();
// Draw a semi-transparent text box onto a bitmap
const
Horz_Margin = 8;
Vert_Margin = 3;
Center_Text = False;
var
x, y: integer;
tw, rw, rh: integer;
iec: TIECanvas;
ss: string;
begin
ss := 'This is my text';
x := 100;
y := 100;
iec := TIECanvas.Create( Bitmap.Canvas );
iec.Font.Size := 30;
iec.Font.Style := [fsBold];
tw := iec.TextWidth(ss);
rw := imax( tw + 2 * Horz_Margin, iec.TextWidth( ss ) + 2 * Horz_Margin );
rh := iec.TextHeight(ss) + 2 * Vert_Margin;
if Center_Text then
dec( x, rw div 2 );
iec.Brush.Color := clYellow;
iec.Brush.Style := bsSolid;
iec.Brush.Transparency := 196;
iec.Pen.Color := clBlack;
iec.Pen.Style := psSolid;
iec.Rectangle( x, y, x + rw, y + rh );
iec.Brush.Style := bsClear;
iec.TextOut(x + ( rw - tw ) div 2, y + Vert_Margin, ss);
iec.Free;
end;
// Gradient text with border
ImageEnView1.IEBitmap.IECanvas.Font.Size := 54;
ImageEnView1.IEBitmap.IECanvas.Font.Style := [fsBold];
ImageEnView1.IEBitmap.IECanvas.Font.Color := clRed;
ImageEnView1.IEBitmap.IECanvas.TextStyling.BorderWidth := 3;
ImageEnView1.IEBitmap.IECanvas.TextStyling.BorderColor := clBlack;
ImageEnView1.IEBitmap.IECanvas.TextStyling.FillColor2 := clYellow;
ImageEnView1.IEBitmap.IECanvas.TextStyling.FillGradient := gpgVertical;
ImageEnView1.IEBitmap.IECanvas.DrawText( 'ImageEn!', 280, 200 );
ImageEnView1.Update();
// Highlight an area of a bitmap
iec := TIECanvas.Create( Bitmap.Canvas, false );
iec.Brush.Color := clRed;
iec.Brush.Style := bsSolid;
iec.Brush.Transparency := 125;
iec.FillRect( Rect( 650, 680, 850, 780 ));
iec.Free();
// Draw an anti-aliased ellipse onto a TBitmap
iec := TIECanvas.Create( ABitmap.Canvas );
with iec do
begin
Pen.Style := psSolid;
Pen.Width := 3;
Pen.Mode := pmCopy;
Pen.Color := clRed;
Brush.Style := bsClear;
Ellipse( Rect( 100, 100, 200, 200 ));
end;
iec.Free();
// Method to draw one of ImageEn's predefined shapes to a canvas
procedure IEDrawShape(Canvas: TIECanvas;
Shape: TIEShape;
Left, Top, Width, Height: Integer;
BorderColor: TColor; BorderWidth: Integer;
FillColor: TColor; FillColor2: TColor = clNone; FillGradient: TIEGDIPlusGradient = gpgVertical;
AntiAlias: Boolean = True;
Angle: Integer = 0;
ShapeModifier: Integer = 0);
var
arPts : Array[ 0 .. Max_Shape_Array_Points ] of TPoint;
drawPts : Array[ 0 .. Max_Shape_Array_Points ] of TPoint;
currX, currY: Integer;
exWidth, exHeight: Integer;
i: Integer;
ptCount: Integer;
begin
IEGenerateShapePoints( arPts, ptCount, Shape, 0, 0, 1000, 1000,
Angle, False,
ShapeModifier,
Width / Height );
if BorderColor = clNone then
BorderWidth := 0;
exWidth := imax( 0, ( Width - BorderWidth ));
exHeight := imax( 0, ( Height - BorderWidth ));
for i := 0 to ptCount - 1 do
begin
currX := arPts[ i ].x;
currY := arPts[ i ].y;
drawPts[i].x := Left + BorderWidth div 2 + round( currX / 1000 * exWidth );
drawPts[i].y := Top + BorderWidth div 2 + round( currY / 1000 * exHeight );
end;
// PAINT TO CANVAS
if AntiAlias then
Canvas.SmoothingMode := iesmAntialias
else
Canvas.SmoothingMode := iesmBestPerformance;
with Canvas do
begin
if BorderWidth > 0 then
begin
Pen.Style := psSolid;
Pen.Width := BorderWidth;
Pen.Color := BorderColor;
end
else
Pen.Style := psClear;
Pen.Mode := pmCopy;
Pen.LineJoin := ieljRound;
if FillColor = clNone then
Brush.Style := bsClear
else
begin
Brush.Color := FillColor;
Brush.Style := bsSolid;
end;
if FillColor2 = clNone then
Brush.SetGradient( gpgNone, 0, 0 )
else
begin
Brush.SetGradient( FillGradient, Width, Height );
Brush.BackTransparency := 255;
Brush.BackColor := FillColor2;
end;
Polygon( slice( drawpts, ptCount ));
end;
end;
// Method to draw a styled ellipse to a canvas
procedure IEDrawSimpleShape(Canvas: TIECanvas;
Left, Top, Width, Height: Integer;
BorderColor: TColor; BorderWidth: Integer;
FillColor: TColor; FillColor2: TColor = clNone;
FillGradient: TIEGDIPlusGradient = gpgVertical;
AntiAlias: Boolean = True);
const
Rect_Rounding = 20;
var
drawGradient: Boolean;
begin
drawGradient := ( FillGradient <> gpgNone ) and
( FillColor2 <> FillColor ) and
( FillColor <> clNone ) and ( FillColor2 <> clNone );
if AntiAlias then
Canvas.SmoothingMode := iesmAntialias
else
Canvas.SmoothingMode := iesmBestPerformance;
// Border
if ( BorderColor = clNone ) or ( BorderWidth < 1 ) then
Canvas.Pen.Style := psClear
else
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := BorderColor;
Canvas.Pen.Width := BorderWidth;
// Fill
if ( FillColor = clNone ) then
Canvas.Brush.Style := bsClear
else
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := FillColor;
inc( Left , BorderWidth div 2 );
inc( Top , BorderWidth div 2 );
dec( Width , BorderWidth );
dec( Height, BorderWidth );
if drawGradient = False then
Canvas.Brush.SetGradient( gpgNone, 0, 0 )
else
begin
Canvas.Brush.SetGradient( FillGradient, Width, Height );
Canvas.Brush.BackTransparency := 255;
Canvas.Brush.BackColor := FillColor2;
end;
Canvas.Ellipse( Left, Top, Left + Width, Top + Height );
end;
// Method to draw text within an area of a TIEBitmap
procedure TextOutEx(aBMP: TIEBitmap;
X, Y, W, H : Integer; const Text : String;
const sFontName : String; iFontSize : Integer; cFontColor : TColor; Style : TFontStyles;
Angle : Integer = 0;
bAntiAlias : Boolean = true; bAutoEnlarge : Boolean = False);
var
AnExtent: TSize;
Mask: TIEMask;
x1, y1, x2, y2: Integer;
CompCanvas: TIECanvas;
iAlpha: Integer;
begin
aBMP.Canvas.Font.Name := sFontName;
aBMP.Canvas.Font.Size := iFontSize;
aBMP.Canvas.Font.Color := cFontColor;
aBMP.Canvas.Font.Style := Style;
AnExtent := aBMP.IECanvas.MeasureText( Text );
if Angle <> 0 then
AnExtent := IERotatePoint2( AnExtent.cx, AnExtent.cy, Angle );
if bAutoEnlarge and (( aBMP.Width < AnExtent.cx ) or ( aBMP.Height < AnExtent.cy )) then
begin
iAlpha := 255;
if aBMP.HasAlphaChannel then
iAlpha := aBMP.Alpha[0, 0];
aBMP.Resize( iMax( aBMP.Width, AnExtent.cx ), iMax( aBMP.Height, AnExtent.cy ), Background, iAlpha);
end;
CompCanvas := aBMP.CreateROICanvas(Rect(0, 0, aBMP.Width, aBMP.Height), bAntiAlias, true, bAntiAlias);
try
if not bAntiAlias then // Cannot use together with alpha composting
CompCanvas.TextRendering := ietrTextRenderingHintSingleBitPerPixel;
CompCanvas.Brush.Color := aBMP.Canvas.Font.Color;
CompCanvas.Font.Color := aBMP.Canvas.Font.Color;
CompCanvas.Font.Name := aBMP.Canvas.Font.Name;
CompCanvas.Font.Height := aBMP.Canvas.Font.Height;
CompCanvas.Font.Style := aBMP.Canvas.Font.Style;
if ( W = 0 ) and ( H = 0 ) then
CompCanvas.DrawText( Text, X, Y, -Angle )
else
CompCanvas.DrawText( Text, Rect( X, Y, X + W, Y + H ), -Angle );
finally
CompCanvas.Free();
end;
end;
// Draw a pointer
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawLine( 40, 30, 200, 100,
clBlack, 2,
ieesArrow, ieesCircle,
20, clRed );
ImageEnView1.Update();
// Draw a line pointer with a label
ImageEnView1.IEBitmap.IECanvas.Font.Name := 'Tahoma';
ImageEnView1.IEBitmap.IECanvas.Font.Size := 8;
ImageEnView1.IEBitmap.IECanvas.Font.Style := [fsBold];
ImageEnView1.IEBitmap.IECanvas.Font.Color := clBlack;
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawLine( 140, 30, 240, 100,
clBlack, 2,
ieesArrow, ieesNone,
20, clRed,
ielpAtEnd, 'Labeled Pointer',
nil, True,
iesRectangle, clRed, clYellow,
gpgVertical );
ImageEnView1.Update();
// Draw a filled 5-pointed star
var
pp: array[0..10] of TPoint;
begin
ImageEnView1.IEBitmap.IECanvas.Pen.Color := clOrangeRed;
ImageEnView1.IEBitmap.IECanvas.Pen.Width := 3;
ImageEnView1.IEBitmap.IECanvas.Brush.Color := clYellow;
pp[0] := Point(175, 50);
pp[1] := Point(205, 145);
pp[2] := Point(300, 145);
pp[3] := Point(225, 205);
pp[4] := Point(253, 300);
pp[5] := Point(175, 243);
pp[6] := Point(98 , 300);
pp[7] := Point(128, 205);
pp[8] := Point(50 , 145);
pp[9] := Point(148, 145);
pp[10] := Point(175, 50);
ImageEnView1.IEBitmap.IECanvas.Polygon(pp);
ImageEnView1.Update();
end;
// Draw an arrow shape
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawShape( 50, 50, 150, 150,
iesShootingArrowSE, 0, 0, // Shape Props
clBlack, 2, 1.0, // Border Props
clYellow, clRed, gpgVertical, 1.0, // Fill Props
True );
ImageEnView1.Update();
// Draw a pink balloon
ImageEnView1.IEBitmap.Allocate( 600, 800 );
ImageEnView1.IEBitmap.Fill( clWhite );
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawShape( 0, 0,
ImageEnView1.IEBitmap.Width,
ImageEnView1.IEBitmap.Height,
iesBalloon, 0, 0, // Shape parameters
clBlack, 2, 1.0, // Border parameters
$00921CF0, clNone, gpgNone, 1.0, // Fill parameters
True );
ImageEnView1.Update();
// Draw a cross
var
pts: array of TPoint;
begin
SetLength( pts, 12 );
pts[0] := Point( 50, 0 );
pts[1] := Point( 100, 50 );
pts[2] := Point( 150, 0 );
pts[3] := Point( 200, 50 );
pts[4] := Point( 150, 100 );
pts[5] := Point( 200, 150 );
pts[6] := Point( 150, 200 );
pts[7] := Point( 100, 150 );
pts[8] := Point( 50, 200 );
pts[9] := Point( 0, 150 );
pts[10] := Point( 50, 100 );
pts[11] := Point( 0, 50 );
ImageEnView1.IEBitmap.IECanvas.AdvancedDrawPolyline( pts, True,
clBlack, 2, 1.0, // Line Props
clYellow, clRed, gpgDiagCenter, 1.0 ); // Fill Props
ImageEnView1.Update();
end;
// Draw a custom rounded, semi-transparent scrollbar
const
RX = 12; // round width
RY = 12; // round height
MINSLIDERW = 8; // minimum slider width
var
scrollPos, scrollCount: integer;
sliderWidth: double;
x, y, Width, Height: Integer;
begin
x := 100;
y := 100;
Width := 300;
Height := 16;
scrollCount := 20;
scrollPos := 3;
with ImageEnView1.IEBitmap.IECanvas do
begin
// paint brush and border
Brush.Style := bsSolid;
Brush.Color := clWhite;
Brush.Transparency := 64;
Pen.Color := clWhite;
Pen.Style := psSolid;
Pen.Mode := pmCopy;
Pen.Width := 1;
Pen.Transparency := 128;
RoundRect( x, y, x + width, y + height, RX, RY );
// paint slider
Brush.Style := bsSolid;
Brush.Color := clBlack;
Brush.Transparency := 128;
Pen.Width := 1;
Pen.Transparency := 128;
sliderWidth := width / scrollCount;
if sliderWidth < MINSLIDERW then
sliderWidth := MINSLIDERW;
RoundRect( x + trunc(scrollPos * sliderWidth), y + 1, x + trunc(scrollPos * sliderWidth) + trunc(sliderWidth), y + height - 1, RX, RY);
end;
ImageEnView1.Update();
end;
// Method to draw a pointer arrow from LineX1,LineY1 to LineX2, LineY2
// IEDrawLineArrow( ImageEnView1.IEBitmap.IECanvas, 650, 680, 850, 780, 30, 30, clBlack, 2, clYellow );
// ImageEnView1.Update();
procedure IEDrawLineArrow(Canvas: TIECanvas; LineX1, LineY1, LineX2, LineY2: integer; ArrowW, ArrowH: integer;
BorderColor: TColor; BorderWidth: Integer; FillColor: TColor);
const
A90 = PI / 2;
var
aa, bb, hw: double;
pp: array[0..2] of TPoint;
p1x, p1y: integer;
begin
// Border
if ( BorderColor = clNone ) or ( BorderWidth < 1 ) then
Canvas.Pen.Style := psClear
else
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := BorderColor;
Canvas.Pen.Width := BorderWidth;
// Fill
if ( FillColor = clNone ) then
Canvas.Brush.Style := bsClear
else
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := FillColor;
Canvas.DrawLine( LineX1, LineY1, LineX2, LineY2 );
hw := ArrowW / 2;
aa := IEAngle( LineX1, LineY1, LineX2, LineY2, LineX1, LineY2 );
if LineX1 = LineX2 then
if LineY1 < LineY2 then
aa := -A90
else
aa := A90;
if ((LineX1 > LineX2) and (LineY2 < LineY1)) or ((LineX1 < LineX2) and (LineY1 < LineY2)) then
bb := 2 * pi - aa + A90
else
bb := aa + A90;
if ((LineX2 < LineX1) and (LineY2 > LineY1)) or ((LineX2 < LineX1) and (LineY2 < LineY1)) or ((LineX1 < LineX2) and (LineY1 = LineY2)) then
begin
p1x := LineX1 + trunc(cos(bb - A90) * ArrowH);
p1y := LineY1 + trunc(sin(bb - A90) * ArrowH);
end
else
begin
p1x := LineX1 + trunc(cos(bb + A90) * ArrowH);
p1y := LineY1 + trunc(sin(bb + A90) * ArrowH);
end;
pp[0].x := p1x + trunc(cos(bb) * hw);
pp[0].y := p1y + trunc(sin(bb) * hw);
pp[1].x := p1x + trunc(cos(bb + pi) * hw);
pp[1].y := p1y + trunc(sin(bb + pi) * hw);
pp[2].x := LineX1;
pp[2].y := LineY1;
Canvas.Polygon(pp);
end;