Четверг, 02.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нужен форум на сайте?
Всего ответов: 90
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Графика » Разные

Основы создания графического редактора типа Paint в Delphi 7

Доброго времени суток!

Ключевые вопросы для этой статьи

  1. Что использовать для редактора?
  2. Какими инструментами пользоваться?
  3. Какие приемы используются?

Сделаем редактор с 5 инструментами, которые показывают основные технологии: карандаш, прямоугольник, эллипс, ломаная, заливка.

Начнем.

Фаза 1: Проектируем форму

Основным элементом на форме будет, конечно же, картинка. Есть несколько вариантов компонентов для нее. Это Image, PaintBox и другие со свойством Canvas.

Остановим свой выбор на PaintBox’е.

Так же нужно не забывать, что картинка может быть больше, чем размеры формы. Для решения этой проблемы, используем ScrollBox.

Для панели инструментов выберем нижнюю часть окна - установим Panel.

Кнопки на панели – SpeedButton.

Итак,

  1. Устанавливаем Panel, свойства Align=alBottom, Height=65.
  2. На панель ставим 5 штук SpeedButton. У всех свойство GroupIndex=1 или другому числу. Главное, чтоб было одинаково. Одной из кнопок назначим Down=True
  3. 2 штуки ColorBox на панель инструментов, в свойстве Style – cbPrettyNames=True. Второму присвоим Selected=clWhite.
  4. Подпишем их «Цвет» и «Фон» соответственно с помощью Label.
  5. Устанавливаем на форму ScrollBox, ставим у него свойство Align=alClient.
  6. Внутрь ScrollBox ставим PaintBox. Ставим свойства Top=0 и Left=0, Align=alNone.
  7. Также сделаем меню. Поставим MainMenu, сделаем в нем 1 меню - «Файл» с пунктами: Открыть, Сохранить, Выход.

Вот то, что вышло у меня после этих действий:

Фаза 2: Программирование

Форму мы спроектировали. Можно начать писать непосредственно программу.

Рисовать мы будем не на холсте PaintBox’a, как можно подумать сначала, а в памяти. На холст будем выводить лишь результат работы.

Для этого объявим глобальные img, buffer:TBitmap;

x0,y0:integer;

Также переменную dwn:boolean, которая будет говорить нажата левая кнопка или нет. (рисовать или нет).

Объявим тип TShape=(sPen, sRect, sEllipse, sPoly, sFill);

И глобальную переменную nowdrawing:TShape;

В ней будет хранится тип фигуры, которую мы рисуем.

В событии формы OnCreate напишем

 Img:=TBitmap.Create;
 buffer:=TBitmap.Create;
 img.Width:=PaintBox1.ClientWidth;
 buffer.Width:=PaintBox1.ClientWidth;
 img.Height:=PaintBox1.ClientHeight;
 buffer.Height:=PaintBox1.ClientHeight;
 nowdrawing:=sPen;
 dwn:=false;

В событии OnMouseDown PaintBox’a проверяем, нажата ли левая кнопка. Если да, то устанавливаем значение nowdrawing’a в нужное, а также сохраняем текущую картинку и начальне координаты мыши. Если это заливка, то нам не нужно учитывать движение мыши, нам достаточно одного нажатия. Поэтому, если заливка, то снимаем флаг dwn, чтоб не реагировать на движения.

Если мы рисуем ломаную линию, то реагировать нужно и на правую кнопку: для создания нового узла. Т.е. для рисования ломанной нужно держать левую кнопку нажатой, а для создания узлов кликать правую кнопку.

Если нажата не левая кнопка, то начальные координаты просто переписываем (x0,y0).
 if button=mbLeft then begin
 img.assign(buffer);
 x0:=x; y0:=y;
 if SpeedButton1.Down then
 begin
 nowdrawing:=sPen;
 img.canvas.MoveTo(x,y);
 end else
 if SpeedButton2.Down then
 nowdrawing:=sEllipse else
 if SpeedButton3.Down then
 nowdrawing:=sRect else
 if SpeedButton4.Down then
 nowdrawing:=sPoly else
 if SpeedButton5.Down then
 nowdrawing:=sFill;
 dwn:=true;
 img.Canvas.Pen.Color:=ColorBox1.Selected;
 img.Canvas.Brush.Color:=ColorBox2.Selected;

 if nowdrawing=sFill then
 begin
 img.Canvas.FloodFill(x0,y0,img.Canvas.Pixels[x,y],fsSurface);
 buffer.Assign(img);
 dwn:=false;
 end
 end else
 begin
 if (dwn)and(nowdrawing=sPoly) then begin
 x0:=x;
 y0:=y;
 buffer.Assign(img);
 end;
 end;

paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),img.Canvas,bounds(0,0,img.Width,img.Height)); 
В событии OnMouseMove самое интересное:

Если флаг dwn не включен, то выходим сразу же из процедуры.

Восстанавливаем старый холст и по выбору рисуемой фигуры в nowdrawing соответственно рисуем линию, прямоугольник, эллипс или отрезок – часть ломаной на картинке img. В конце рисования, переносим его на холст PaintBox’a.

 if not dwn then exit;
 img.assign(buffer);
 case nowdrawing of
 sPen:begin
 img.Canvas.LineTo(x,y);
 buffer.Assign(img);
 end;
 sRect:begin
 img.Canvas.Rectangle(x0,y0,x,y);
 end;
 sEllipse:begin
 img.Canvas.Ellipse(x0,y0,x,y);
 end;
 sPoly:begin
 img.Canvas.MoveTo(x0,y0);
 img.Canvas.LineTo(x,y);
 end;
 sFill:begin
 //nothing.
 end;
 end;
 paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),img.Canvas,bounds(0,0,img.Width,img.Height));

В событии OnMouseUp:

if button=mbLeft then dwn:=false;
buffer.Assign(img);

И, в заключение, в собитии OnPaint PaintBox’a напишем прорисовку картинки из буфера.

paintbox1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height),buffer.Canvas,bounds(0,0,img.Width,img.Height));

Вот и все! У нас есть костяк редактора. Можно легко добавлять новые функции, модифицировать старые.

По всем вопросам пишите на antigluk@gmail.com или icq: 4732698.

Исходник здесь.

Получить ссылку на материал

Категория: Разные | Добавил: Барон (20.12.2011)
Просмотров: 11288 | Теги: Paint, Редактор, delphi | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
DirectX [17]
OpenGL [2]
Игры [15]
Разные [28]
Королевство Delphi © 2010-2024
Яндекс цитирования