Создание инструментов рисования




Сначала рассмотрим возможности работы с графикой в Delphi.

Для выполнения операций рисования необходим класс TCanvas. С помощью его свойств и методов можно рисовать на поверхности видимых объектов, которые имеют свойство Canvas, таких как форма Form и графический образ Image. Canvas переводится как «поверхность», «холст для рисования». Холст состоит из отдельных точек – пикселей. Положение пикселя характеризуется его горизонтальной (X) и вертикальной (Y) координатами. Левый верхний пиксель имеет координаты (0, 0). Координаты возрастают сверху вниз и слева направо. Значения координат правой нижней точки холста зависят от размера холста.

Любая поверхность рисования включает объекты пера TPen, кисти TBrush и шрифта TFont. Объекты пера и кисти используются для геометрических фигур, а объект шрифта позволяет управлять атрибутами текста, выводимого на поверхности объекта. Основные свойства пера Pen – это цвет (Color), Стиль (Style), Толщина (Width). У кисти Brush наиболее часто используются свойства Цвет (Color) и Стиль (Style).

Свойство Canvas доступно только при выполнении программы, поэтому получаемые с его помощью рисунки являются динамическими. Они существуют только тогда, когда приложение работает.

Для рисования нам понадобятся три события: OnMouseDown (нажатие кнопки мыши), OnMouseMove (перемещение мыши), OnMouseUp (отпускание кнопки мыши).

Процедуры обработчики событий OnMouseDown и OnMouseUp имеют одинаковые параметры

(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer)

  • Sender –здесь храниться объект, который сгенерировал событие.
  • Button – здесь храниться признак клавиши, которая была нажата. Этот параметр может быть равен: mbLeft (нажата левая кнопка), mbRight (нажата правая кнопка) или mbMiddle (нажата средняя кнопка).
  • Shift – состояние дополнительных клавиш клавиатуры. Этот параметр может хранить любые из следующих значений ssShift – нажата клавиша Shift, ssAlt – нажата клавиша Alt, ssCtrl – нажата клавиша Ctrl, ssLeft – нажата левая кнопка мыши, ssRight – нажата правая кнопка мыши, ssMiddle – нажата средняя кнопка, ssDouble – был двойной щелчок мышкой.
  • X,Y – последние два параметра – это координаты, в которых была нажата кнопка мыши.
  1. Опишите в разделе public модуля формы следующие переменные: z типа byte, drawing типа boolean.
  2. Переменная z будет содержать номер текущего инструмента рисования. Поэтому в событие OnClick кнопки «Карандаш» добавьте код z:=1; аналогично, для Ластика – z:=2; для Линии – z:=3; и т.д. до 7.

Карандаш

Карандаш работает следующим образом:

  • при нажатии кнопки мыши на компонент Image1 начинается рисование, и указатель текущей позиции перемещается в положение щелчка мыши;
  • при перемещении мыши рисуется линия из текущей позиции до нового положения мыши;
  • при отпускании мыши рисование заканчивается.

Для признака рисования будет использоваться переменная drawing типа Boolean. Если эта переменная равна true, то пользователь нажал кнопку мыши и при перемещении мыши должно происходить рисование.

По событию OnCreate для формы мы должны задать переменной drawing значение по умолчанию – false, ведь после старта приложения кнопка мыши еще не нажата мышь, и при перемещении мыши рисование происходить не должно.

  1. Чтобы избежать случайного попадания в переменную drawing значения True,напишите следующий код (для выделения формы воспользуйтесь Инспектором объектов):

procedure TMainForm.FormCreate(Sender: TObject);

begin

drawing:=false;

end;

  1. По нажатию кнопки мыши OnMouseDown на компонент Image1 напишите следующий код:

procedure TMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

drawing:=true;

with Image1.Canvas do

case z of

1: MoveTo(x,y);

end;

end;

Оператор выбора case здесь используется потому, что дальше нам придется выбирать номер текущего инструмента рисования. Если сейчас используется карандаш, то указатель текущего положения смешается в положение мыши X, Y.

  1. Теперь напишите обработчик события OnMouseMove, который генерируется при каждом перемещении мыши:

procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

begin

if drawing then with Image1.Canvas do

case z of

1: LineTo(X,Y);

end;

end;

В первой строчке происходит проверка, если переменная drawing равна true, то сейчас происходит рисование и поэтому рисуется линия до точки X, Y.

  1. По событию OnMouseUp присвойте переменной drawing значение false.

Инструмент «Карандаш» должен быть автоматически выбран при запуске программы, т.е. переменная z должна иметь значение 1, а кнопка «Карандаш» должна находится в нажатом состоянии. Создадим вспомогательную процедуру Start, которая будет устанавливать все исходные свойства используемых компонентов, и будем вызывать ее сначала при создании формы, а затем каждый раз при создании нового документа.

  1. В разделе type модуля формы опишите процедуру

procedure Start;

  1. Создайте процедуру

procedure TMainForm.Start;

begin

z:=1; ToolButton1.Down:=True;

end;

  1. А теперь в обработчике события OnCreate формы MainForm вызовите эту процедуру, т.е. добавьте код

Start;

Ластик

Ластик работает также как и карандаш, только рисует не основным цветом, а цветом фона. Основной цвет рисования содержится в свойстве холста Pen.Color, а цвет фона – в Brush.Color. Поэтому при включении инструмента Ластик необходимо изменить цвет пера на цвет кисти, а после окончания работы с Ластиком восстановить исходное значение.

  1. В разделе public опишите вспомогательную переменную BufColor типа TColor, в которой будет содержаться старое значение цвета пера.
  2. В операторе выбора case процедуры Image1MouseDown добавьте еще один вариант:

procedure TMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

drawing:=true;

with Image1.Canvas do

case z of

1: MoveTo(x,y);

2: begin

BufColor:= Image1.Canvas.Pen.Color;

Image1.Canvas.Pen.Color:=Image1.Canvas.Brush.Color;

MoveTo(x,y);

end;

end;

end;

  1. При перемещении мыши Ластик выполняет действия, аналогичные Карандашу, поэтому измените обработчик события OnMouseMove следующим образом:

procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

begin

if drawing then with Image1.Canvas do

case z of

1,2: LineTo(X,Y);

end;

end;

  1. Событие OnMouseUp измените на:

procedure TMainForm.Image1MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

drawing:=false;

with Image1.Canvas do

case z of

2: Image1.Canvas.Pen.Color:=BufColor;

end;

end;

Здесь цвет пера восстанавливается из вспомогательной переменной BufColor.

Линия

Линия работает следующим образом:

  • при нажатии кнопки мыши на компонент Image1 начинается рисование, мы запоминаем текущие координаты точки, где был произведен щелчок мышью;
  • при движении мыши рисуется линия из начальной точки до текущей;
  • при отпускании мыши рисование заканчивается и на холсте остается только последняя линия.

Для того чтобы при движении мыши на холсте оставалась только одна линия, а не все промежуточные, нужно затирать старые линии и восстанавливать то, что было под ними.

  1. Добавьте в раздел public переменные:

OldPenMode:TPenMode;

StartX, StartY, OldX, OldY:Integer;

Переменные StartX, StartYбудут использоваться для запоминания координат начала линии, а переменные OldX, OldYнужны для хранения конечных координат линии. В переменной OldPenMode будет сохраняться текущее значение режима рисования.

Примечание: У пера (свойство Pen холста) есть очень много режимов рисования. Режимы рисования устанавливаются в свойстве Mode пера. Это свойство имеет тип TPenModeи может принимать следующие значения: pmBlack, pmWhite, pmNop, pmNot,pmCopy, pmNotXorи так далее.

  1. В операторе выбора case обработчика события MouseDown добавьте очередной вариант

3: begin

OldPenMode:=Canvas.Pen.Mode;

Pen.Mode:=pmNotXor;

StartX:=X; StartY:=Y; OldX:=X; OldY:=Y;

end;

Сначала мы сохраняем текущий режим рисования в переменной OldPenMode. В следующей строке меняем режим на pmNotXor. В таком режиме, когда мы рисуем первый раз какую-то фигуру, то она выводиться в нормальном виде. Если нарисовать ее второй раз, то она просто стирается и старое изображение восстанавливается на экране. Далее мы просто запоминаем координаты StartX, StartY, OldX и OldY.

  1. В обработчик события OnMouseMove добавьте вариант

3: begin

MoveTo(StartX, StartY); LineTo(OldX,OldY);

MoveTo(StartX, StartY); LineTo(X,Y);

OldX:=X; OldY:=Y;

end;

Сначала мы рисуем линию из начальной позиции до старой, где она была нарисована на прошлом шаге. Так как используется режим pmNotXor, то повторное рисования линии в старой позиции просто восстанавливает старое значение. После этого мы рисуем фигуру в новой позиции и сохраняем текущую позицию Х и Y в переменных OldXи OldY.

  1. В процедуру MouseUp добавьте вариант

3: begin

Pen.Mode:=OldPenMode;

MoveTo(StartX,StartY); LineTo(X,Y);

end;

Здесь сначала восстанавливается старое значение режима рисования, а затем рисуется уже окончательный вариант линии.

Прямоугольник, эллипс

Для рисования прямоугольника используется метод Rectangle (x1, y1, x2, y2), где x1, y1 и х2, у2 – координаты левого верхнего и правого нижнего углов прямоугольника. А для рисования эллипса – Ellipse (x1, y1, х2, у2), где x1, y1, х2, у2 – координаты прямоугольника, внутри которого вычерчивается эллипс.

Рисование прямоугольника и эллипса происходит аналогично рисованию линии:

  • при нажатии кнопки мыши мы запоминаем текущие координаты точки;
  • при движении мыши фигура перерисовывается от стартовой позиции до текущей;
  • при отпускании мыши рисование заканчивается и холсте остается только последняя фигура.
  1. Поскольку при событии OnMouseDown выполняются те же действия, что и для линии (т. е. при z=3,4,5 действия одинаковые), нужно только дописать варианты 4 и 5 к варианту 3:

3,4,5: begin …

  1. В событии OnMouseMove добавьте два новых варианта

4: begin

Rectangle(StartX, StartY, OldX, OldY);

Rectangle(StartX, StartY, X, Y);

OldX:=X; OldY:=Y;

end;

5: begin

Ellipse(StartX, StartY, OldX, OldY);

Ellipse(StartX, StartY, X, Y);

OldX:=X; OldY:=Y;

end;

  1. В событии OnMouseUp добавьте

4: begin Pen.Mode:=OldPenMode; Rectangle(StartX,StartY,X,Y); end;

5: begin Pen.Mode:=OldPenMode; Ellipse(StartX,StartY,X,Y); end;

Заливка

Для инструмента Заливка используем метод

FloodFill (X, Y: double; Color: TColor; FillStyle: TFillStyle);

Этот метод заполняет холст, используя текущую кисть. FloodFill начинается в точке (X, Y) и заполняет область, ограниченную указанной цветом Color. Параметр FillStyle определяет способ заполнения используемый (fsBorder заполняет до тех пор, пока не встретит указанный цвет, и fsSurface заполняет, пока встречается указанный цвет).

Поскольку заливка происходит просто при щелчке мыши, нам понадобится только событие OnMouseDown. Добавьте в него вариант

6: FloodFill(X, Y, Pixels[X,Y], fsSurface);

Свойство Pixels [X,Y] определяет цвет точки с координатами [X,Y]. Таким образом, наш инструмент Заливка определяет цвет точки, в которой был произведен щелчок мышью, и заливает окрашенную этим цветом область цветом кисти холста.

Надпись

Работа инструмента Надпись заключается в том, чтобы по щелку мыши выводить на рисунке набранный пользователем текст.

Для вывода текста на холст используется процедура TextOut (x, у, Текст), где х, у – координаты точки графической поверхности, на которой выполняется вывод текста, а Текст – переменная или константа символьного типа, значение которой задает выводимый текст.

Фактически, инструмент Надпись должен выполнять следующие действия:

  • по щелчку мыши запоминать текущие координаты;
  • открывать окно для ввода текста пользователем;
  • выводить этот текст в заданной точке.

Примечание: Область вывода текста закрашивается текущим цветом кисти. Поэтому перед выводом текста свойству Brush.Style нужно присвоить значение bsClear или задать цвет кисти, совпадающий с цветом поверхности, на которую выводится текст.

  1. В разделе public модуля опишите переменную BufStyle типа TBrushStyle, в ней будет содержаться текущий стиль кисти.
  2. В обработчик события OnMouseDown рисунка Image1 добавьте еще один вариант

7: begin

BufStyle:=Brush.Style; Brush.Style:=bsClear;

s:=InputBox('Ввод текста', 'Введите текст:','');

TextOut(X,Y,s);

Brush.Style:=BufStyle;

end;

А в разделе var это процедуры опишите переменную s типа string.

Данная процедура очищает стиль кисти, вызывает стандартное диалоговое окно InputBox для ввода текста, выводит на рисунок текст, а затем восстанавливается стиль кисти.

Создание палитры цветов

  1. С помощью Инспектора Объектов выделите форму MainForm. Перейдите на страницу Win32 Палитры компонентов и дважды щелкните мышью по компоненту ToolBar. В результате на форме появится еще одна панель инструментов. На нее мы и поместим компоненты палитры.
  2. Выделите панель Toolbar2, задайте для нее выравнивание (Align) по нижнему краю (alBottom), в свойстве AutoSize выберите True (это свойство разрешает компоненту автоматически изменять свои размеры в зависимости от размеров содержащихся в нем компонентов).

Рис. 4. Промежуточный вид формы MainForm.

  1. На эту панель инструментов поместите панель Panel со страницы Standard шириной (Width) 50 и высотой (Height) 50, удалите ее заголовок (Caption). Поэкспериментируйте со свойствами панели BevelInner, BevelOuter, определяющими тип внутренней и внешней кромки панели. В это панели будет содержаться информация об основном цвете и цвете фона.
  2. Внутри этой панели Panel разместите еще одну панель размером 20 на 20, удалите ее заголовок Caption и задайте тип границы.
  3. Скопируйте эту панель и вставьте новую рядом с ней (см. рис. 4). Первая панель предназначена для отображения основного цвета, а вторая – для цвета фона. Измените имена этих панелей (Name) на pnMain и pnBgr соответственно.
  4. Изначально основной цвет рисования черный, а цвет фона – белый, поэтому в процедуре Start добавьте код:

pnMain.Color:=clBlack; pnBgr.Color:=clWhite;

  1. Поместите на панель инструментов ToolBar2 еще одну панель Panel, которая будет содержать стандартный набор цветов. Удалите ее заголовок (Caption) и задайте вид границ. Поместите на нее компонент ColorCrid со страницы Samples.

Примечание: таблица цветов ColorGrid предназначена для выбора основного и фонового цвета из 16-цветной палитры. Основной цвет выбирается щелчком левой кнопки мыши, отображается символами FG и содержится в свойстве ForegroundColor, а фоновый цвет выбирается правой кнопкой, отображается символами BG и содержится в свойстве BackgroundColor (если оба цвета совпадают, соответствующая клетка таблицы помечается символами FB).

  1. Измените свойство GridOrdering компонента ColorCrid1 на go8x2, ширину (Width) задайте равной 168, а высоту (Height) – 40. В процедуру Start добавьте строчки

ColorGrid1.ForegroundIndex:=0;

ColorGrid1.BackgroundIndex:=15;

  1. Создайте для ColorCrid1 процедуру

procedure TMainForm.ColorGrid1Change(Sender: TObject);

begin

with Image1.Canvas do begin

Pen.Color:=ColorGrid1.ForegroundColor;

pnMain.Color:=Pen.Color;

Brush.Color:=ColorGrid1.BackgroundColor;

pnBgr.Color:=Brush.Color;

Font.Color:=Pen.Color;

end;

end;

Эта процедура изменяет цвет пера на основной цвет, а цвет кисти на цвет фона и выводит эти цвета на соответствующие панели.

  1. Теперь создадим возможность выбирать не стандартные, а произвольные цвета. Для этого понадобится диалоговое окно ColorDialog со страницы Dialogs. Поместите его на форму.
  2. На панели для выбора цветов поместите две кнопки SpeedButton (см. рис. 4). Задайте для них размеры 20 на 20 и с помощью свойства Glyph поместите на них изображения pen.bmp и fill.bmp из папки Buttons.
  3. Задайте для них значение свойства Flat равным True. В свойстве Hint наберите «Основной цвет|Выбор основного цвета рисования» и «Цвет фона|Выбор цвета фона» соответственно, а затем измените свойство ShowHint на True.
  4. Для первой кнопки в обработчик события OnClick добавьте код

ColorDialog1.Color:=Image1.Canvas.Pen.Color;

if ColorDialog1.Execute then begin

Image1.Canvas.Pen.Color:=ColorDialog1.Color;

pnMain.Color:=ColorDialog1.Color;

end;

  1. Для второй кнопки создайте процедуру

procedure TMainForm.SpeedButton2Click(Sender: TObject);

begin

ColorDialog1.Color:=Image1.Canvas.Brush.Color;

if ColorDialog1.Execute then begin

Image1.Canvas.Brush.Color:=ColorDialog1.Color;

pnBgr.Color:=ColorDialog1.Color;

end;

end;

  1. Теперь можно запустить проект и проверить его работу. На данном этапе графический редактор может использовать все свои инструменты и менять основной и фоновый цвет.


Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-10-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: