Sign in Join
Wiki copytemporary

BGRABitmap tutorial 11: what changed

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

OldNewLine
11This tutorial shows how to combine transformations. A sample project can be found in [[BGRABitmap AggPas]].
22
33### Create a new project
44
55Create a new project and add a reference to [[BGRABitmap]], the same way as in [[BGRABitmap tutorial|the first tutorial]].
66
77### Affine transformation of a radial gradient
88
99Here is an affine transformation applied on a gradient like we did with textures:
1010
1111``` pascal
1212uses BGRAGradientScanner, BGRATransform;
1313
1414procedure TForm1.FormPaint(Sender: TObject);
1515var image: TBGRABitmap;
1616 grad: TBGRAGradientScanner;
1717 affine: TBGRAAffineScannerTransform;
1818begin
1919 image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
2020
2121 grad := TBGRAGradientScanner.Create(BGRA(0,0,255),BGRAWhite,gtRadial,PointF(0,0),PointF(1,0),True,True);
2222
2323 affine := TBGRAAffineScannerTransform.Create(grad);
2424 affine.Scale(150,80);
2525 affine.RotateDeg(-30);
2626 affine.Translate(ClientWidth/2, ClientHeight/2);
2727
2828 image.Fill(affine);
2929
3030 affine.free;
3131 grad.free;
3232
3333 image.Draw(Canvas,0,0,True);
3434 image.free;
3535end;
3636```
3737
3838The base gradient is radial, centered at origin (0,0), of radius 1.
3939
4040The affine transformation does the following:
4141
4242- stretch the gradient to a size of 150x80
4343- rotate 30 degrees in counterclockwise direction
4444- center it in the form
4545
4646The Fill instruction draws the result into the image.
4747
4848### Run the program
4949
5050You should obtain a blue and white ellipse gradient.
5151
52-<figure>
53-<img src="BGRATutorial11a.png" title="BGRATutorial11a.png" />
54-<figcaption>BGRATutorial11a.png</figcaption>
55-</figure>
52+![](/wiki-images/a/a9/BGRATutorial11a.png)
5653
5754### Combine with a twirl
5855
5956We can add another transformation to it like this:
6057
6158``` pascal
6259var image: TBGRABitmap;
6360 grad: TBGRAGradientScanner;
6461 affine: TBGRAAffineScannerTransform;
6562 twirl: TBGRATwirlScanner;
6663begin
6764 image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
6865
6966 grad := TBGRAGradientScanner.Create(BGRA(0,0,255),BGRAWhite,gtRadial,PointF(0,0),PointF(1,0),True,True);
7067
7168 affine := TBGRAAffineScannerTransform.Create(grad);
7269 affine.Scale(150,80);
7370 affine.RotateDeg(-30);
7471 affine.Translate(ClientWidth/2, ClientHeight/2);
7572
7673 twirl := TBGRATwirlScanner.Create(affine,Point(ClientWidth div 2, ClientHeight div 2),100);
7774 image.Fill(twirl);
7875 twirl.Free;
7976
8077 affine.free;
8178 grad.free;
8279
8380 image.Draw(Canvas,0,0,True);
8481 image.free;
8582end;
8683```
8784
8885Here, we simply create a twirl transformation applied to the previous one, and fill with it.
8986
9087### Run the program
9188
9289Now the center of the gradient is twirled.
9390
94-<figure>
95-<img src="BGRATutorial11b.png" title="BGRATutorial11b.png" />
96-<figcaption>BGRATutorial11b.png</figcaption>
97-</figure>
91+![](/wiki-images/b/b0/BGRATutorial11b.png)
9892
9993### Use a custom scanner
10094
10195We may want to create our own gradient generator. Here is for example a multiply gradient:
10296
10397``` pascal
10498type
10599 { TBGRAMultiplyScanner }
106100
107101 TBGRAMultiplyScanner = class(TBGRACustomScanner)
108102 function ScanAt(X, Y: Single): TBGRAPixel; override;
109103 end;
110104
111105{ TBGRAMultiplyScanner }
112106
113107function TBGRAMultiplyScanner.ScanAt(X, Y: Single): TBGRAPixel;
114108 function cycle512(value: integer): integer; inline;
115109 begin
116110 result := value and 511;
117111 if result >= 256 then result := 511-result;
118112 end;
119113
120114var
121115 mul: integer;
122116begin
123117 mul := cycle512(round(x*y));
124118 result := BGRA(mul,mul,mul,255);
125119end;
126120```
127121
128122It is derived from TBGRACustomScanner to be used for filling, and the ScanAt function is overridden. It computes the product of both coordinates and make a cycle of 512 with it (from 0 to 255 and then from 255 down to 0).
129123
130124Let's draw it on the screen with a simple affine transformation:
131125
132126``` pascal
133127var image: TBGRABitmap;
134128 grad: TBGRAMultiplyScanner;
135129 affine: TBGRAAffineScannerTransform;
136130begin
137131 image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
138132
139133 grad := TBGRAMultiplyScanner.Create;
140134 affine := TBGRAAffineScannerTransform.Create(grad);
141135 affine.Scale(6,4);
142136 affine.Translate(ClientWidth/2, ClientHeight/2);
143137 image.Fill(affine);
144138 affine.free;
145139 grad.free;
146140
147141 image.Draw(Canvas,0,0,True);
148142 image.free;
149143end;
150144```
151145
152146### Run the program
153147
154148It should look like this:
155149
156-<figure>
157-<img src="BGRATutorial11c.png" title="BGRATutorial11c.png" />
158-<figcaption>BGRATutorial11c.png</figcaption>
159-</figure>
150+![](/wiki-images/e/e0/BGRATutorial11c.png)
160151
161152### Make it beautiful
162153
163154Add some colors by modifying the ScanAt procedure of the multiply gradient:
164155
165156``` pascal
166157var
167158 mul: integer;
168159begin
169160 mul := round(x*y);
170161 result := BGRA(cycle512(round(x*10)),cycle512(mul),cycle512(round(y*10)),255);
171162end;
172163```
173164
174165The red and blue intensities are filled with a cycle of x and y positions.
175166
176167And add some rotation:
177168
178169``` pascal
179170 affine := TBGRAAffineScannerTransform.Create(grad);
180171 affine.Scale(6,4);
181172 affine.RotateDeg(-30);
182173 affine.Translate(ClientWidth/2, ClientHeight/2);
183174```
184175
185-<figure>
186-<img src="BGRATutorial11d.png" title="BGRATutorial11d.png" />
187-<figcaption>BGRATutorial11d.png</figcaption>
188-</figure>
176+![](/wiki-images/e/e8/BGRATutorial11d.png)
189177
190178[[BGRABitmap tutorial 10|Previous tutorial (texture mapping)]] [[BGRABitmap tutorial 12|Next tutorial (text functions)]]
191179
192180---
193181*From the Free Pascal wiki, page "BGRABitmap tutorial 11", as it stood on 2023-05-20 after a change by Circular, 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).*
194182Category: BGRABitmap
195183Category: Graphics

Back to history