Drawing Shapes in Delphi
Believe me, drawing shapes in Delphi is so easy. To develop a software like CAD, Paint, CorelDraw Delphi provides large number of classes and members that supports to draw shapes on a form or on a graphic control. In Delphi, we draw shapes on canvas of a form or graphic controls. Canvas is an area of form where we can draw shapes, lines and can fill colors on shapes. In Delphi, every form or graphic controls have Canvas property which provides TCanvas object that can be used to draw shapes. TPen object is used to draw lines and we can set size, color of lines. TBrush object is used to set color and style to fill the shapes. Most frequently used classes for drawing shapes are TCanvas , TBitmap, TGraphics, TPen, TBrush
Use TCanvas as a drawing surface for objects that draw an image of themselves
TBitmap
Bitmap is a powerful graphics object used to create, manipulate (scale, scroll, rotate, and paint), and store images in memory and as files on a disk.
TGraphics
TGraphics is the abstract base class type for objects such as icons, bitmaps, and meta files that can store and display visual images. It cannot be instantiated.
TPen
used to draw lines or outline shapes on a canvas.
TBrush
represents the color and pattern used to fill solid shapes.
TRect
Class which provides a rectangle area of points (left, top, bottom, right)
TFont
Class to change font name, size , color and style when we draw a text.
Even though form’s have also canvas property it’s not a good practice to draw shapes on Delphi forms because we may put other controls on form and may draw on top of the other controls which will result a undesirable result. Even when we minimize and maximize a form you see the drawing image will cleared automatically because after minimize when we maximize the form it tries to repaint the form area to already drawn images will be cleared.
So here in my blog I have used TImage control and its Canvas property to draw shapes. I will also explain how to save the drawing to a bitmap file, how to clear the Canvas and how to re-display the previously saved image.
Every drawing is calculated by position point like a pixel point mostly on basis of x axis and y axis.
So now let's have a look at TImage component example that will draw shapes on Canvas.
I have put a TImage component on form and set following properties.
object imgDrawArea: TImage
Left = 0
Top = 0
Align = alClient
end
and also put a Button control which on click I will draw shapes on imgDrawArea Canvas.
object btnDraw: TButton
Left = 192
Top = 144
Width = 75
Height = 33
Caption = 'Draw'
TabOrder = 0
OnClick = btnDrawClick
end
and I have written codes on button click. Here I am drawing a line from point (50,50) to (150,150)
procedure TForm1.btnDrawClick(Sender: TObject);
begin
with imgDrawArea do
begin
Canvas.MoveTo(50,50);
Canvas.LineTo(150, 150);
End;
end;
Lets draw lines and different shapes in Delphi using Canvas, Pen and Brush.
Draw a Line.
To draw a line first we need to set initial point that we can set by using Canvas.Moveto procedure and then we need to call Canvas.LineTo method to draw a line.
with imgDrawArea do
Canvas.MoveTo(50,50);
After set initial point draw a lint to destination point that we can set by using Canvas.LineTo procedure.
with imgDrawArea do
Canvas.LineTo(150, 150);
So here in above example it will draw a line from point (50,50) to (150,150)
Changing Color, Size, Style of line by using TPen object
Delphi provides TPen class to manage lines. Canvas property as Pen property which can be used to change size, color and style of line. Please make sure that we should set all pen related property before drawing shapes.
with imgDrawArea do
begin
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 3;
Canvas.MoveTo(50,50);
Canvas.LineTo(150, 150);
End;
Changing line style
Please note that dash or dot style will only effect when Pen width is 1.
with imgDrawArea do
begin
Canvas.Pen.Width := 1;
Canvas.Pen.Color := clBlue;
Canvas.Pen.Style := psDash;
Canvas.MoveTo(70,70);
Canvas.LineTo(170, 170);
Canvas.Pen.Color := clRed;
Canvas.Pen.Style := psDashDot;
Canvas.MoveTo(170,70);
Canvas.LineTo(70, 170);
End;
Draw rectangle
with imgDrawArea do
Canvas.Rectangle(70, 70, 200, 200);
Change Line color and size.
with imgDrawArea do
begin
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 2;
End;
Fill color and style.
To fill color and style in rectangle or any covered area we can use TBrush object and its members.
Color
with imgDrawArea do
Canvas.Brush.Color := clBlue;
No color
with imgDrawArea do
Canvas.Brush.Style := bsClear;
Style
with imgDrawArea do
Canvas.Brush.Style := bsVertical;
with imgDrawArea do
Canvas.Brush.Style := bsFDiagonal;
with imgDrawArea do
Canvas.Brush.Style := bsCross;
Canvas.Brush.Style := bsCross;
Draw a round rectangle
with imgDrawArea do
Canvas.RoundRect(60, 60, 200, 200, 10, 10);
Fille with color and style
with imgDrawArea do
begin
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clGreen;
Canvas.Brush.Style := bsDiagCross;
Canvas.RoundRect(60, 60, 200, 200, 10, 10);
End;
Draw Focus Rect
var
R: TRect;
begin
with imgDrawArea do
begin
R := Rect(100, 100, 200, 200);
Canvas.DrawFocusRect(R);
end;
Draw circle
with imgDrawArea do
begin
Canvas.Pen.Width := 2;
Canvas.Pen.Color := clRed;
Canvas.Brush.Color := clGreen;
Canvas.Ellipse(50, 50, 200, 200);
End;
Draw Polygon
with imgDrawArea do
begin
Canvas.Pen.Color := clBlue;
Canvas.Brush.Color := clTeal;
Canvas.Polygon([Point(70, 70), Point(250, 250), Point(320, 70),
Point(240, 120)]);
end;
Draw Polyline
with imgDrawArea do
begin
Canvas.Pen.Color := clRed;
Canvas.Polyline([Point(140, 110), Point(90, 190), Point(200, 140),
Point(80, 140), Point(190, 190), Point(140, 110)])
end;
Draw Arc
with imgDrawArea do
begin
Canvas.Pen.Color := clRed;
Canvas.Arc(70, 70, 150, 150, 150, 150, 70, 70 );
end;
Draw Chord
with imgDrawArea do
begin
Canvas.Pen.Color := clBlue;
Canvas.Chord(100, 100, 300, 300, 300, 100, 100, 100);
end;
Draw a Pie
with imgDrawArea do
begin
Canvas.Pen.Color := clWhite;
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := clLime;
Canvas.Pie (MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100));
Canvas.Brush.Color := clCream;
Canvas.Pie (MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 15, 100),
MulDiv(Height, 85, 100));
Canvas.Brush.Color := clAqua;
Canvas.Pie (MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 55, 100));
Canvas.Brush.Color := clMoneyGreen;
Canvas.Pie (MulDiv(Width, 15, 100),
MulDiv(Height, 55, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 15, 100),
MulDiv(Height, 85, 100),
MulDiv(Width, 45, 100),
MulDiv(Height, 85, 100));
end;
Fill a area with FloodFill
procedure TForm1.btnDrawClick(Sender: TObject);
var
ewidth, eheight: integer;
begin
with imgDrawArea do
begin
ewidth := 300;
eheight := 200;
Canvas.Brush.Color := clRed;
Canvas.Pen.Color := clBlack;
Canvas.Ellipse(
(ClientWidth - ewidth) div 2,
(ClientHeight - eheight) div 2,
ewidth, eheight);
end;
end;
procedure TForm1.btnFloodFillClick(Sender: TObject);
var
R: TRect;
sText: string;
begin
with imgDrawArea do
begin
Canvas.Brush.Color := clBlue;
Canvas.Brush.Style := bsCross;
Canvas.FloodFill( ClientWidth div 2, ClientHeight div 2, clYellow, fsBorder);
end;
end;
Draw a Text
We can draw text using TextOut or TextRect function. So lets see.
TextOut
with imgDrawArea do
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clBlue;
Canvas.Font.Size := 20;
Canvas.Font.Style := [fsItalic];
Canvas.TextOut(50, 100, 'Jitendra Gouda');
end;
TextRect
var
sText: string;
begin
with imgDrawArea do
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clRed;
Canvas.Font.Size := 10;
Canvas.Font.Style := [fsBold];
sText := 'Hello, world!';
Canvas.TextRect(imgDrawArea.ClientRect,50,100,sText);
end;
Draw Text with different format like center, wrap, framerect
Example 1
var
Rect1: TRect;
sText: string;
begin
with imgDrawArea do
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clGreen;
Canvas.Font.Size := 10;
Canvas.Font.Style := [fsBold];
sText := 'Hello, world!. Drawing Text with different format.';
Rect1 := Rect(50, 100, 300, 200);
Canvas.TextRect(Rect1, sText, [tfCenter, tfWordBreak]);
Canvas.Brush.Color := clRed;
Canvas.FrameRect(Rect1);
end;
end;
Example 2
var
Rect1: TRect;
sText: string;
begin
with imgDrawArea do
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clPurple;
Canvas.Font.Size := 10;
Canvas.Font.Style := [fsBold];
sText := 'Hello, world!.';
Rect1 := Rect(50, 100, 300, 200);
Canvas.TextRect(Rect1, sText, [tfSingleLine, tfCenter, tfVerticalCenter]);
Canvas.Brush.Color := clSkyBlue;
Canvas.FrameRect(Rect1);
end;
end;
TextHeight and TextWidth
var
Rect1: TRect;
sText: string;
iTextHeight, iTextwidth: integer;
begin
with imgDrawArea do
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clGreen;
Canvas.Font.Size := 10;
Canvas.Font.Style := [fsBold];
sText := 'Hello, world!.';
iTextHeight := Canvas.TextHeight(sText);
iTextwidth := Canvas.TextWidth(sText);
Rect1 := Rect(50, 100, 50+iTextwidth, 100+iTextHeight);
Canvas.TextRect(Rect1, sText, [tfCenter, tfWordBreak]);
Canvas.Brush.Color := clRed;
Canvas.FrameRect(Rect1);
end;
end;
Draw a Triangle
With imgDrawArea do
begin
Canvas.Pen.Color := clBlue;
Canvas.Pen.Width := 2;
Canvas.Brush.Color := clSkyBlue;
Canvas.Brush.Style := bsSolid;
Canvas.Polygon([Point(150, 50), Point(50, 250), Point(250, 250)]);
end;
Draw a Star
var
i, x, y, xx, yy: Integer;
p: array[0..9] of TPoint;
t, r, sv, sw, sx, sy, s: Real;
Rect: TRect;
FRegion: HRGN;
Begin
With imgDrawArea do
begin
Rect := ClientRect;
InflateRect(Rect, -2, -2); //decreases rectangle size by 2//
sx := (Rect.Right-Rect.Left)*0.48;
sy := (Rect.Bottom-Rect.Top)*0.5;
if sx > sy then
sx := sy
else
sy := sx;
sv := (Rect.Left + Rect.Right) / 2;
sw := (Rect.Top + Rect.Bottom * 1.2) / 2.2;
for i := 0 to 10 do
begin
if ((i and 1) <> 0) then
r := 1
else
r := 0.384;
t := i * 2 * (PI/10);
P[i].x := Trunc(sv+sx*r*sin(t));
P[i].Y := Trunc(sw+sy*r*cos(t));
end;
FRegion := CreatePolygonRgn(P, 10, WINDING);
Canvas.Pen.Color := clRed;
Canvas.Pen.Width := 2;
Canvas.Brush.Color := clYellow;
Canvas.Brush.Style := bsSolid;
Canvas.Polygon(P);
end;
end;
Save drawing to a file
imgDrawArea.Picture.Bitmap.SaveToFile('c:\jitendra\test1.bmp');
Load drawing from a file
imgDrawArea.Picture.Bitmap.LoadFromFile('c:\jitendra\test1.bmp');
Nice examples. The TRect summary should read (Left, Top, Right, Bottom)
ReplyDeleteHello There. I found your blog using msn. This is a very well written article. I’ll make sure to bookmark it and return to read more of your useful information. Thanks for the post. I’ll definitely return. mac service berlin
ReplyDeleteFamilies Portrait Wir Zeichnen Jede Deiner Idee Du hast nie die Gelegenheit ein Bild mit einem geliebten Menschen zu machen und suchst das perfekte Geschenkt für Deine Familie Dann bist Du bei uns genau richtig Foto zeichnen lassen
ReplyDeleteGreat Blog, thank you for sharing with us
ReplyDeleteclick on this link
Amazon PPC & Advertising Management
ReplyDeleteThis article is very informative! I was wondering if you could elaborate on online branding and digital marketing course in krishnagiri
ReplyDelete