Основи створення графічного редактора типу Paint в Delphi, Різне, Програмування, статті

Ключові питання цієї статті:
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));

От і все! У нас є кістяк редактора. Можна легко додавати нові функції, модифікувати старі.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*