Графические возможности Delphi. Canvas.
Canvas обеспечивает пространство (холст, канву) для создания, хранения и модификации графических объектов. Canvas является основой графической подсистемы Delphi. Канва обеспечивает:
Ø Загрузку и хранение графических изображений
Ø Создание новых и изменение хранимых изображений с помощью пера, кисти, шрифта
Ø Рисование и закраску различных фигур, линий, текстов
Ø Комбинирование различных изображений
Система координат
Для того, чтобы мы могли что-либо нарисовать на форме или компоненте (Canvas поддерживают многие компоненты), нам нужно уметь задавать положение на экране того, что мы рисуем. Для этого с канвой связывается система координат следующего вида:
Обратите внимание. Точка (0,0) находится в левом верхнем углу. Привычная для нас система координат “перевернута”
Каждая точка на самом деле представляет собой очень маленький прямоугольник (И поскольку это не совсем точка, то используются термин — “пиксел”).
Основные методы Canvas
Рассмотрим часть методов, при помощи которых можно создавать простые рисунки.
Arc
Рисует дугу окружности или эллипса
Arc(x1,y1,x2,y2,x3,y3,x4,y4: Integer)
Метод Arc рисует дугу окружности или эллипса с помощью текущих параметров пера Pen (эти параметры мы рассмотрим чуть ниже). Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки.
Пример.
Image1.Canvas.Arc(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Arc(0,0, 200,200, 0,0, 200,0);
Chord
Рисует заполненную замкнутую фигуру, ограниченную дугой окружности или эллипса и хордой
Chord (x1,y1,x2,y2,x3,y3,x4,y4:Integer);
Метод Chord рисует замкнутую фигуру: дугу окружности или эллипса, замкнутую хордой, с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush (рассмотрим чуть ниже). Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки. Хорда соединяет точки(x3,y3) и (x4,y4).
Пример.
Image1.Canvas.Chord(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Chord(0,0, 200,200, 0,0, 200,0);
Draw
Рисует графическое изображение в указанную позицию канвы
Draw (x,y:Integer;Graphic:TGraphic);
Метод Draw рисует изображение, содержащееся в объекте, указанном параметром Graphic, сохраняя исходный размер изображеня в его источнике и перенося изображение в область канвы объекта TCanvas, верхний левый угол которой определяется параметрами x и y. Источник изображения может быть битовой матрицей, пиктограммой или метафайлом.
Пример.
Form1.Canvas.Draw(10,10,Bitmap1);
Рисует на канве формы Form1 изображение из компонента Bitmap1 в область с координатами левого верхнего угла (10,10).
DrawFocusRect
Рисует изображение прямоугольника в виде, используемом для отображения рамки фокуса, операцией XOR
DrawFocusRect (const Rect:TRect);
Метод DrawFocusRect рисует на канве в области Rect изображение прямоугольника в виде, используемом обычно для отображения рамки фокуса, т.е. точками. При рисовании используется операция XOR, что позволяет удалить изображение прямоугольника его повторной прорисовкой.
Пример.
Следующая совокупность обработчиков событий, связанных с мышью, рисует на канве компонента Image1 прямоугольную рамку размером 10 на 10 вокруг курсора и перетаскивает еепри перемещении мыши с нажатой кнопкой:
Var x0,y0:Integer;
Const drag:Boolean=False;
Procedure TForm1.Image1MouseDown(Sender: TObject;Button: TMouseButton;Shift: TShiftState;X, Y: Integer);
Begin
{рисование рамки}
Image1.Canvas.DrawFocusRect(Rect(x-5,y-5,x+5,y+5));
{запоминание координат курсора}
X0:=x;
Y0:=y;
{включение флажка режима перемещения рамки}
Drag:=True;
End;
Procedure TForm1.Image1MouseMove(Sender: TObject;Shift: TShiftState;X,Y: Integer);
Begin
If not drag then exit;
{стирание рамки}
Image1.Canvas.DrawFocusRect(Rect(X0-5,Y0-5,X0+5,Y0+5));
{рисование рамки}
Image1.Canvas.DrawFocusRect(Rect(X-5,Y-5,X+5,Y+5));
{запоминание координат курсора}
X0:=X;
Y0:=Y;
End;
Procedure TForm1.Image1MouseUp(Sender: TObject;Button: TMouseButton;Shift: TShiftState;X,Y: Integer);
Begin
If not drag then exit;
{стирание рамки}
Image1.Canvas.DrawFocusRect(Rect(X0-5,Y0-5,X0+5,Y0+5));
{выключение флажка режима перемещения рамки}
drag:=false;
End;
При нажатии кнопки мыши рисуется первая рамка, запоминаются координаты курсора и включается режим перемещения рамки (переменная drag = True). При перемещении мыши в режиме перемещения рамки стирается прежняя рамка, рисуется рамка в новой позиции и запоминаются новые координаты курсора. При отпускании кнопки мыши стирается рамка и выключается режим перемещения рамки.
Ellipse
Рисует заполненную окружность или эллипс
Ellipse (x1,y1,x2,y2:Integer);
Метод Ellipse рисует окружность или эллипс с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush. Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс.
Пример.
With Image1.Canvas do //в операторных скобках перед каждой строкой добавляет Image1.Canvas.
Begin
Brush.Color := clRed;
Brush.Style := bsDiagCross;
Ellipse(0, 0, Image1.Width, Image1.Height);
End;
FillRect
Заполняет указанный прямоугольник канвы, используя текущее значение Brush.
FillRect(const: TRect);
Метод FillRect заполняет прямоугольник канвы, указанный параметром Rect, используя текущее значение Brush. Заполняемая область включает верхнюю и левую стороны прямоугольника, но не включает правую и нижнюю стороны.
Пример.
Image1.Canvas.FillRect(Rect(0,0,Width,Height));
Очищает всю канву компонента Image1, заполняя ее фоном, если он установлен в свойстве Brush.
FloodFill
Закрашивает текущей кистью замкнутую область канвы, определенным цветом.
Type TFillStyle = (fsSurfase, fsBorder);
Procedure FloodFill (x,y:Integer;Color:TColor;FillStyle:TFillStyle);
Метод FloodFill закрашивает текущей кистью Brush замкнутую область канвы, определенным цветом и начальной точкой закрашивания (x,y). Точка с координатами x и y является произвольной внутренней точкой заполняемой области, которая может иметь произвольную форму. Граница этой области определяется сочетанием параметров Color и FillStyle. Параметр Color указывает цвет, который используется при определении границы закрашиваемой области, а параметр FillStyle определяет, как именно по этому цвету определяется граница. Если FillStyle = fsSurface, то заполняется область, закрашенная цветом Color, а на других цветах метод останавливается. Если FillStyle = fsBorder, то наоборот, заполняется область окрашенная любыми цветами, не равными Color, а на цвете Color метод останавливается.
Примеры.
1.
With Image1.Canvas do begin
Brush.Color:=clWhite;
FloodFill(X,Y,Pixels[X,Y],fsSurface);
End;
Приведенные операторы закрашивают белым цветом на канве компонента Image1 все пиксели, прилегающие к пикселю с координатами (x,y) и имеющие тот же цвет, что и этот пиксель.
2.
With Image1.Canvas do begin
Brush.Color:=clWhite;
FloodFill(X,Y,clBlack, fsBorder);
End;
Приведенные операторы закрашивают белым цветом на канве компонента Image1 все пиксели, прилегающие к пикселю с координатами (x,y) и имеющие цвет, отличный от черного. При достижении черной границы области закраска останавливается.
FrameRect
Рисует на канве текущей кистью прямоугольную рамку.
FrameRect(const Rect:TRect);
Метод FrameRect рисует на канве прямоугольную рамку вокруг области Rect, используя установку текущей кисти Brush. Толщина рамки — 1 пиксель. Область внутри рамки кистью не закрашивается. Отличается от метода Rectangle тем, что рамка рисуется цветом кисти (в методе Rectangle — цветом пера Pen) и область не закрашивается (в методе Rectangle закрашивается).
Пример.
With Form1.Canvas do
Begin
Brush.Color:=clBlack;
FrameRect(Rect(10,10,100,100));
End;
Рисует на канве формы Form1 черную рамку.
LineTo
Рисует на канве прямую линию, начинающуюся с текущей позиции пера и кончающуюся указанной точкой.
LineTo (x,y:Integer);
Метод LineTo рисует на канве прямую линию, начинающуюся с текущей позиции пера PenPos и кончающуюся точкой (x,y). Текущая позиция пера PenPos перемещается и кончающуюся точкой (x,y), исключая саму точку (x,y). Текущая позиция пера PenPos перемещается в точку (x,y). При рисовании используются текущие установки пера Pen.
Пример.
Form1.Canvas.MoveTo(x1,y1);
Form1.Canvas.LineTo(x2,y2);
Form1.Canvas.LineTo(x3,y3);
Рисует кусочно-ломаную прямую, соединяющую точки (x1,y1), (x2,y2) и (x3,y3).
MoveTo
Изменяет текущую позицию пера на заданную, ничего не рисуя при этом.
MoveTo(x,y:Integer);
Метод MoveTo изменяет текущую позицию пера на заданную точкой (x,y). Это эквивалентно непосредственной установке свойства PenPos. При перемещении пера методом MoveTo ничего не рисуется.
Pie
Рисует заполненную замкнутую фигуру — сегмент окружности или эллипса.
Pie (x1,y1,x2,y2,x3,y3,x4,y4:Longint);
Метод Pie рисует замкнутую фигуру — сектор окружности или эллипса, с помощью текущих параметров пера Pen. Фигура заполняется текущим значением Brush. Точки (x1,y1) и (x2,y2) определяют прямоугольник, описывающий эллипс. Начальная точка дуги определяется пересечением эллипса с прямой, проходящейчерез его центр и точку (x3,y3). Конечная точка дуги определяется пересечением эллипса с прямой, проходящей через его центр и точку (x4,y4). Дуга рисуется против часовой стрелки от начальной до конечной точки. Рисуются прямые, ограничивающие сегмент и проходящие через центр эллипса и точки (x3,y3) и (x4,y4).
Пример.
Image1.Canvas.Pie(0,0, 200,200, 200,0, 0,0);
Image2.Canvas.Pie(0,0, 200,200, 0,0, 200,0);
Polygon
Рисует на канве текущим пером замкнутую фигуру (многоугольник) по заданному множеству угловых точек, замыкая первую и последнюю точки и закрашивая внутреннюю область фигуру текущей кистью.
Polygon (Points: array of TPoint);
Метод Polygon рисует на канве замкнутую фигуру (полигон, многоугольник) по множеству угловых точек, заданному массивом Points. Первая из указанных точек соединяется прямой с последней. Этим метод Polygon отличается от метода Polyline, который не замыкает конечные точки. Рисование проводится текущим пером Pen. Внутренняя область фигуры закрашивается текущей кистью Brush.
Примеры.
1
Form1.Canvas.Polygon([Point(10,10),Point(30,10),Point(130,30),Point(240, 120)]);
Рисует на канве формы четырехугольник по точкам, заданным функциями Point.
2
Form1.Canvas.Polygon(PointArray);
Рисует на канве формы многоугольник по точкам, хранящимся в массиве PointArray, который может быть объявлен, например, следующим образом:
Var PointArray:array[1..100] of TPoint;
3
Form1.Canvas.Polygon(Slice(PointArray, 10));
Рисует на канве формы многоугольник по первым 10 точкам, хранящимся в массиве PointArray из предыдущего примера.
Polyline
Рисует на канве текущим пером кусочно-линейную кривую по заданному множеству точек.
Polyline(Points: array of TPoint);
Метод Polyline рисует на канве кусочно-линейную кривую по множеству точек, заданному массивом Points. Отличие метода Polyline от метода Polygon заключается в том, что метод Polygon замыкает конечные точки, а метод Polyline — нет. Рисование проводится текущим пером Pen. Метод не изменяет текущей позиции PenPos пера Pen.
Метод позволяет рисовать кусочно-линейный график функции, хранящийся в массиве типа TPoint. Если желательно использовать для рисования только часть точек массива, это можно сделать с помощью функции Slice. Если надо нарисовать кривую всего по нескольким точкам, то передавать их в метод Polyline удобно с помощью функции Point.
То что делает метод Polyline, можно сделать и с помощью методов MoveTo и LineTo, подведя сначало перо к первой точке, а затем последовательно выполняя LineTo. Различие будет заключаться в том, что метод Polyline не изменит текущую пера, а методы MoveTo и LineTo изменят.
Примеры.
1
Form1.Canvas. Polyline([Point(10,10),Point(30,10),Point(130,30),Point(240, 120)]);
Рисует кусочно-линейную кривую по четырем точкам, заданным функциями Point.
2
var PointArray:array[0..100] of TPoint;
procedure TForm1.Button1Click(Sender: TObject);
var i,X,Y:word;
begin
for i:=0 to 100 do begin
X:=Image1.ClientWidth*i div 100;
Y:=trunc((Image1.ClientHeight div 2)*(1+sin(4*Pi*X/Image1.ClientWidth)));
PointArray[i]:=Point(X,Y);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Image1.Canvas.PolyLine(PointArray);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Image1.Canvas.PolyLine(Slice(PointArray,25));
end;
Первая процедура Button1Click заполняет массив PointArray точками, описывающими график функции sin(x) на протяжении двух периодов (4). Вторая процедура Button2Click по точкам из этого массива рисует график на канве компонента Image1. Третья процедура Button3Click использует для рисования графика первые 25 точек этого массива.
Rectangle
Рисует на канве текущим пером прямоугольник и закрашивает его текущей кистью.
Rectangle(x1,y1,x2,y2:Integer);
Метод Rectangle рисует на канве текущим пером Pen прямоугольник, верхний левый угол которого имеет координаты (x1,y1), а нижний правый — (x2,y2). Прямоугольник закрашивается текущей кистью Brush. Рисование прямоугольника без рамки можно осуществить методом FillRect. Прямоугольник со скругленными углами рисуется методом RoundRect. Прямоугольникбез внутренней закраски рисуется методом FrameRect.
Пример.
Image1.Canvas.Rectangle(10,10,210,110);
RoundRect
Рисует на канве прямоугольную рамку со скругленными углами.
RoundRect(x1,y1,x2,y2,x3,y3:Integer);
Метод RoundRect рисует на канве прямоугольную рамку со скругленными углами, используя текущие установки пера Pen и заполняя площадь фигуры текущей кистью Brush. Рамка определяется прямоугольником с координатами углов (x1,y1) и (x2,y2). Углы скругляются с помощью эллипсов с шириной x3 и высотой y3.
Если задать ширину эллипса x3 x2-x1, то верхняя и нижняя границы рамки окажутся целиком скругленными (без прямолинейной части). Если y3 y2-y1, то же самое произойдет с левой и правой границами рамки. Если же оба измерения эллипса не меньше размеров рамки, то будет рисоваться просто эллипс. Но, конечно, для рисования эллипса лучше использовать метод Ellipse. Если один из размеров эллипса задать нулевым, то будет рисоваться прямоугольная рамка, а для получения такой рамки лучше использовать метод Rectangle.
Пример.
Набор следующих операторов вызывает изображения, позанные на приведенномниже рисунке:
with Image1.Canvas do
begin
RoundRect(10,10,110,210,50,100);
RoundRect(160,10,260,210,100,100);
RoundRect(310,10,410,210,50,200);
RoundRect(460,10,560,210,100,200);
end;
Основные свойства Canvas
Brush
Определяет цвет и стиль заполнения фона окна. Доступен только для чтения.
Brush: TBrush;
Свойство Brush (кисть) присуще многим оконным объектам, включая Canvas. Его можно читать, чтобы определить цвет и стиль заполнения фона окна. Это свойство только для чтения. Однако, атрибуты объекта Brush можно изменять, используя свойства Color и Style.
Color
Цвет фона компонента, цвет текста, объекта, TFont и др.
Color: TColor;
Свойство Color определяет цет фона компонента. Значение цвета может задаваться как значение, определяющее интенсивности красного, зеленого и синего цветов в формате RGB (Например: Form1.Canvas.Brush.Color:= RGB (88, 87, 104)) или равным одной из предопределенных в Delphi констант. Ниже приведены некоторые из них.
Константа |
Значение цвета |
clBlack |
Черный |
clMaroon |
Темно-бордовый |
clGreen |
Зеленый |
clOlive |
Оливково-зеленый |
clNavy |
Темно-синий |
clPurple |
Пурпурный |
clTeal |
Морской воды |
clGray |
Серый |
clSilver |
Серебряный |
clRed |
Красный |
clLime |
Лимонно-зеленый |
clBlue |
Синий |
clYellow |
Желтый |
clFuchsia |
Сиреневый |
clAqua |
Голубой |
clWhite |
Белый |
clBackground |
Текущий цвет фона стола Windows |
clScrollBar |
Текущий цвет полос прокрутки |
Style
Style: TBrushStyle default bsSolid;
Свойство Style определяет шаблон, которым кисть заполняет фон объекта. Возможные значения свойста Style:
Pen
Определяет свойства пера, используемые при рисовании линий и фигур на канве.
Основные свойста:
Color — цвет пера. По умолчанию clBlack.
Style — определяет режимрисования линий.
psSolid |
Сплошная линия |
psDash |
Штриховая линия |
psDot |
Пунктирная линия |
psDashDot |
Штрих-пунктирная линия |
psDashDotDot |
Линия, чередующая штрих и два пунктира |
psClear |
Отсутствующая линия |
psInsideFrame |
Сплошная линия, но при width > 1 допускающая цвета, отличные от палитры windows. |
Width — определяет толщину линии в пикселях. Тип Integer. Влияет на Style.
Пример использования Canvas.
Задание: нарисовать ель.
Программный код:
Procedure TForm1.FormPaint(Sender: TObject);
Begin
With Form1.Canvas do // к каждой последующей строке добавлять Form1.Canvas.
Begin
Pen.Width:=1; //установка полщины пера
Pen.Color:=clGreen; //установка цвета пера
Brush.Color:=clGreen; //установка цвета заливки
{Рисование елки}
PolyGon([Point(350,90),Point(330,90),Point(400,160),Point(380,160),
Point(470,250),Point(130,250),Point(220,160),Point(200,160),
Point(270,90),Point(250,90),Point(300,40)]);
Pen.Color:=RGB(128,64,0); //установка цвета пера (оттенок коричневого)
Brush.Color:=RGB(128,64,0); //установка цвета заливки (оттенок коричневого)
{Рисование ствола}
PolyGon([Point(350,251),Point(350,301),Point(250,301),Point(250,251)]);
End;
Результат работы программы: