Sign in Join
Wiki copytemporary

BGRABitmap tutorial 3/de: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: BGRABitmap tutorial 3/de

OldNewLine
1+Dieses Tutorial zeigt, wie man mit der Maus auf einer Bitmap zeichnet.
2+
3+### Erzeugen Sie ein neues Projekt
4+
5+Erzeugen Sie ein neues Projekt und fügen Sie eine Referenz auf [[BGRABitmap/de|BGRABitmap]] hinzu, genau so wie im [[BGRABitmap tutorial/de|ersten Tutorial]].
6+
7+### Erzeugen Sie ein neues Bild
8+
9+Fügen Sie eine private Variable zum Hauptformular hinzu, um das Bild zu speichern:
10+
11+``` pascal
12+ TForm1 = class(TForm)
13+ private
14+ { private declarations }
15+ image: TBGRABitmap;
16+ public
17+ { public declarations }
18+ end;
19+```
20+
21+Erzeugen Sie das Bild, wenn das Formular erzeugt wird. Dazu doppelklicken Sie auf das Formular, eine Prozedur erscheint im Quelltexteditor. Fügen Sie eine Anweisung zum Erzeugen des Bildes ein:
22+
23+``` pascal
24+procedure TForm1.FormCreate(Sender: TObject);
25+begin
26+ image := TBGRABitmap.Create(640,480,BGRAWhite); //erzeuge ein 640x480 Bild
27+end;
28+```
29+
30+### Zeichnen Sie die Bitmap
31+
32+Fügen Sie einen OnPaint-Handler hinzu. Dazu wählen Sie das Hauptformular aus, gehen zum Objektinspektor, zum Karteireiter Ereignisse und doppelklicken Sie auf die Zeile 'OnPaint'. Dann fügen Sie den Zeichenbefehl ein:
33+
34+``` pascal
35+procedure TForm1.FormPaint(Sender: TObject);
36+begin
37+ PaintImage;
38+end;
39+```
40+
41+Schreiben Sie die Prozedur 'PaintImage':
42+
43+``` pascal
44+procedure TForm1.PaintImage;
45+begin
46+ image.Draw(Canvas,0,0,True);
47+end;
48+```
49+
50+Danach setzen Sie den Mauszeiger auf PaintImage und drücken Strg-Umsch-C, um die Deklaration dem Interface hinzuzufügen.
51+
52+### Behandeln Sie die Maus-Ereignisse
53+
54+Im Objektinspektor fügen Sie für die Ereignisse 'MouseDown' und 'MouseMove' jeweils einen Handler hinzu:
55+
56+``` pascal
57+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
58+ Shift: TShiftState; X, Y: Integer);
59+begin
60+ if Button = mbLeft then DrawBrush(X,Y);
61+end;
62+
63+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
64+ Y: Integer);
65+begin
66+ if ssLeft in Shift then DrawBrush(X,Y);
67+end;
68+```
69+
70+Ergänzen Sie die Prozedur 'DrawBrush':
71+
72+``` pascal
73+procedure TForm1.DrawBrush(X, Y: Integer);
74+const radius = 5;
75+begin
76+ image.GradientFill(X-radius,Y-radius, X+radius,Y+radius,
77+ BGRABlack,BGRAPixelTransparent, gtRadial,
78+ PointF(X,Y), PointF(X+radius,Y), dmDrawWithTransparency);
79+
80+ PaintImage;
81+end;
82+```
83+
84+Danach setzen Sie den Mauszeiger auf DrawBrush und drücken Strg-Umsch-C, um die Deklaration dem Interface hinzuzufügen.
85+
86+Diese Prozedur zeichnet einen radialen Farbverlauft (gtRadial):
87+
88+- das umgebende Rechteck ist (X-radius,Y-radius, X+radius,Y+radius).
89+- die Mitte ist schwarz, der Rand ist transparent
90+- die Mitte ist bei (X,Y) und der Rand bei (X+radius,Y)
91+
92+### Code
93+
94+``` pascal
95+unit UMain;
96+
97+{$mode objfpc}{$H+}
98+
99+interface
100+
101+uses
102+ Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
103+ BGRABitmap, BGRABitmapTypes;
104+
105+type
106+ { TForm1 }
107+
108+ TForm1 = class(TForm)
109+ procedure FormCreate(Sender: TObject);
110+ procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
111+ Shift: TShiftState; X, Y: Integer);
112+ procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
113+ procedure FormPaint(Sender: TObject);
114+ private
115+ { private declarations }
116+ image: TBGRABitmap;
117+ procedure DrawBrush(X, Y: Integer);
118+ procedure PaintImage;
119+ public
120+ { public declarations }
121+ end;
122+
123+var
124+ Form1: TForm1;
125+
126+implementation
127+
128+{ TForm1 }
129+
130+procedure TForm1.FormCreate(Sender: TObject);
131+begin
132+ image := TBGRABitmap.Create(640,480,BGRAWhite);
133+end;
134+
135+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
136+ Shift: TShiftState; X, Y: Integer);
137+begin
138+ if Button = mbLeft then DrawBrush(X,Y);
139+end;
140+
141+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
142+ Y: Integer);
143+begin
144+ if ssLeft in Shift then DrawBrush(X,Y);
145+end;
146+
147+procedure TForm1.FormPaint(Sender: TObject);
148+begin
149+ PaintImage;
150+end;
151+
152+procedure TForm1.DrawBrush(X, Y: Integer);
153+const radius = 20;
154+begin
155+ image.GradientFill(X-radius,Y-radius, X+radius,Y+radius,
156+ BGRABlack,BGRAPixelTransparent,gtRadial,
157+ PointF(X,Y), PointF(X+radius,Y), dmDrawWithTransparency);
158+
159+ PaintImage;
160+end;
161+
162+procedure TForm1.PaintImage;
163+begin
164+ image.Draw(Canvas,0,0,True);
165+end;
166+
167+initialization
168+ {$I UMain.lrs}
169+
170+end.
171+```
172+
173+### Starten Sie das Programm
174+
175+Sie sollten mit der Maus auf dem Formular zeichnen können.
176+
177+<figure>
178+<img src="BGRATutorial3.png" title="BGRATutorial3.png" />
179+<figcaption>BGRATutorial3.png</figcaption>
180+</figure>
181+
182+### Kontinuierliches Zeichnen
183+
184+Für das kontinuierliche Zeichnen brauchen wir zusätzliche Variablen:
185+
186+``` pascal
187+ TForm1 = class(TForm)
188+ ...
189+ private
190+ { private declarations }
191+ image: TBGRABitmap;
192+ mouseDrawing: boolean;
193+ mouseOrigin: TPoint;
194+```
195+
196+'mouseDrawing' ist während des Zeichnens (also bei gedrückter linker Maustaste) TRUE und 'mouseOrigin' ist der Anfangspunkt des zu zeichnenden Segments.
197+
198+Der Klick-Handler wird dadurch ein bisschenkomplizierter:
199+
200+``` pascal
201+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
202+ Shift: TShiftState; X, Y: Integer);
203+begin
204+ if Button = mbLeft then
205+ begin
206+ mouseDrawing := True;
207+ mouseOrigin := Point(X,Y);
208+ DrawBrush(X,Y,True);
209+ end;
210+end;
211+```
212+
213+Er initialisiert die Zeichnung mit der aktuellen Position. Dann zeichnet er ein geschlossenes Segment (beachten Sie den neuen Parameter von DrawBrush). Wirklich, am Anfang wird das Segment geschlossen und hat die Länge Null, das ergibt eine Scheibe:
214+
215+<figure>
216+<img src="BGRATutorial3b.png" title="BGRATutorial3b.png" />
217+<figcaption>BGRATutorial3b.png</figcaption>
218+</figure>
219+
220+Schritt für Schritt fügen wir einen neuen Teil (aber ein offenes Segment) hinzu:
221+
222+<figure>
223+<img src="BGRATutorial3c.png" title="BGRATutorial3c.png" />
224+<figcaption>BGRATutorial3c.png</figcaption>
225+</figure>
226+
227+Darum brauchen wir einen neuen Parameter für die Funktion 'DrawBrush', diese wird zu:
228+
229+``` pascal
230+procedure TForm1.DrawBrush(X, Y: Integer; Closed: Boolean);
231+const brushRadius = 20;
232+begin
233+ image.DrawLineAntialias(X,Y,mouseOrigin.X,mouseOrigin.Y,BGRA(0,0,0,128),brushRadius,Closed);
234+ mouseOrigin := Point(X,Y);
235+
236+ PaintImage;
237+end;
238+```
239+
240+Wir übergen den Parameter 'Closed' an 'DrawLineAntialias', um anzuzeigen, ob das Segment geschlossen ist oder nicht. Beachten Sie die Reihenfolge der Koordinaten. Die Anfangs- und Endposition sind vertauscht. Tatsächlich ist für 'DrawLineAntialias' das Ende offen - wir hingegen wollen in diesem Fall, dass der Anfang offen ist.
241+
242+Die Definition von DrawBrush muss im Interface angepasst werden.
243+
244+Der MouseMove-Handler wird zu:
245+
246+``` pascal
247+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
248+ Y: Integer);
249+begin
250+ if mouseDrawing then DrawBrush(X,Y,False);
251+end;
252+```
253+
254+Zuletzt fügen wir einen MouseUp-Handler hinzu, der 'mouseDrawing' aktualisiert:
255+
256+``` pascal
257+procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
258+ Shift: TShiftState; X, Y: Integer);
259+begin
260+ if Button = mbLeft then
261+ mouseDrawing := False;
262+end;
263+```
264+
265+### Code
266+
267+``` pascal
268+unit UMain;
269+
270+{$mode objfpc}{$H+}
271+
272+interface
273+
274+uses
275+ Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
276+ BGRABitmap, BGRABitmapTypes;
277+
278+type
279+ { TForm1 }
280+
281+ TForm1 = class(TForm)
282+ procedure FormCreate(Sender: TObject);
283+ procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
284+ Shift: TShiftState; X, Y: Integer);
285+ procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
286+ procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
287+ Shift: TShiftState; X, Y: Integer);
288+ procedure FormPaint(Sender: TObject);
289+ private
290+ { private declarations }
291+ image: TBGRABitmap;
292+ mouseDrawing: boolean;
293+ mouseOrigin: TPoint;
294+ procedure DrawBrush(X, Y: Integer; Closed: boolean);
295+ procedure PaintImage;
296+ public
297+ { public declarations }
298+ end;
299+
300+var
301+ Form1: TForm1;
302+
303+implementation
304+
305+{ TForm1 }
306+
307+procedure TForm1.FormCreate(Sender: TObject);
308+begin
309+ image := TBGRABitmap.Create(640,480,BGRAWhite);
310+end;
311+
312+procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
313+ Shift: TShiftState; X, Y: Integer);
314+begin
315+ if Button = mbLeft then
316+ begin
317+ mouseDrawing := True;
318+ mouseOrigin := Point(X,Y);
319+ DrawBrush(X,Y,True);
320+ end;
321+end;
322+
323+procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
324+ Y: Integer);
325+begin
326+ if mouseDrawing then DrawBrush(X,Y,False);
327+end;
328+
329+procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
330+ Shift: TShiftState; X, Y: Integer);
331+begin
332+ if Button = mbLeft then
333+ mouseDrawing := False;
334+end;
335+
336+procedure TForm1.FormPaint(Sender: TObject);
337+begin
338+ PaintImage;
339+end;
340+
341+procedure TForm1.DrawBrush(X, Y: Integer; Closed: Boolean);
342+const brushRadius = 20;
343+begin
344+ image.DrawLineAntialias(X,Y,mouseOrigin.X,mouseOrigin.Y,BGRA(0,0,0,128),brushRadius,Closed);
345+ mouseOrigin := Point(X,Y);
346+
347+ PaintImage;
348+end;
349+
350+procedure TForm1.PaintImage;
351+begin
352+ image.Draw(Canvas,0,0,True);
353+end;
354+
355+initialization
356+ {$I UMain.lrs}
357+
358+end.
359+```
360+
361+### Starten Sie das Programm
362+
363+Jetzt ist das Zeichnen nahezu kontinuierlich:
364+
365+<figure>
366+<img src="BGRATutorial3d.png" title="BGRATutorial3d.png" />
367+<figcaption>BGRATutorial3d.png</figcaption>
368+</figure>
369+
370+[[BGRABitmap tutorial 2/de|Voriges Tutorial (Laden eines Bildes)]] \| [[BGRABitmap tutorial 4/de|Nächstes Tutorial (direkter Zugriff auf die Pixel)]]
371+
372+---
373+*From the Free Pascal wiki, page "BGRABitmap tutorial 3/de", as it stood on 2020-02-10 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history