1Imager::Engines(3) User Contributed Perl Documentation Imager::Engines(3)
2
3
4
6 Imager::Engines - Programmable transformation operations
7
9 use Imager;
10
11 my %opts;
12 my @imgs;
13 my $img;
14 ...
15
16 my $newimg = $img->transform(
17 xexpr=>'x',
18 yexpr=>'y+10*sin((x+y)/10)')
19 or die $img->errstr;
20
21 my $newimg = Imager::transform2(\%opts, @imgs)
22 or die "transform2 failed: $Imager::ERRSTR";
23
24 my $newimg = $img->matrix_transform(
25 matrix=>[ -1, 0, $img->getwidth-1,
26 0, 1, 0,
27 0, 0, 1 ]);
28
30 transform()
31 The transform() function can be used to generate spatial warps and
32 rotations and such effects. It only operates on a single image and its
33 only function is to displace pixels.
34
35 It can be given the operations in postfix notation or the module
36 Affix::Infix2Postfix can be used to generate postfix code from infix
37 code. Look in the test case t/t55trans.t for an example.
38
39 transform() needs expressions (or opcodes) that determine the source
40 pixel for each target pixel. Source expressions are infix expressions
41 using any of the +, -, *, / or ** binary operators, the - unary
42 operator, ( and ) for grouping and the sin() and cos() functions. The
43 target pixel is input as the variables x and y.
44
45 You specify the x and y expressions as "xexpr" and "yexpr"
46 respectively. You can also specify opcodes directly, but that's magic
47 deep enough that you can look at the source code.
48
49 Note: You can still use the transform() function, but the transform2()
50 function is just as fast and is more likely to be enhanced and
51 maintained.
52
53 $new_img=$img->transform(xexpr=>'x',yexpr=>'y+10*sin((x+y)/10)')
54
55 $new_img=$img->transform(xexpr=>'x+0.1*y+5*sin(y/10.0+1.57)',
56 yexpr=>'y+10*sin((x+y-0.785)/10)')
57
58 transform2()
59 Imager also supports a transform2() class method which allows you
60 perform a more general set of operations, rather than just specifying a
61 spatial transformation as with the transform() method, you can also
62 perform color transformations, image synthesis and image combinations
63 from multiple source images.
64
65 transform2() takes an reference to an options hash, and a list of
66 images to operate one (this list may be empty):
67
68 my %opts;
69 my @imgs;
70 ...
71 my $img = Imager::transform2(\%opts, @imgs)
72 or die "transform2 failed: $Imager::ERRSTR";
73
74 The options hash may define a transformation function, and optionally:
75
76 • width - the width of the image in pixels. If this isn't supplied
77 the width of the first input image is used. If there are no input
78 images an error occurs.
79
80 • height - the height of the image in pixels. If this isn't supplied
81 the height of the first input image is used. If there are no input
82 images an error occurs.
83
84 • constants - a reference to hash of constants to define for the
85 expression engine. Some extra constants are defined by Imager
86
87 • channels - the number of channels in the output image. If this
88 isn't supplied a 3 channel image will be created.
89
90 The transformation function is specified using either the "expr" or
91 "rpnexpr" member of the options.
92
93 Infix expressions
94
95 You can supply infix expressions to transform 2 with the "expr"
96 keyword.
97
98 $opts{expr} = 'return getp1(w-x, h-y)'
99
100 The 'expression' supplied follows this general grammar:
101
102 ( identifier '=' expr ';' )* 'return' expr
103
104 This allows you to simplify your expressions using variables.
105
106 A more complex example might be:
107
108 $opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)'
109
110 Currently to use infix expressions you must have the Parse::RecDescent
111 module installed (available from CPAN). There is also what might be a
112 significant delay the first time you run the infix expression parser
113 due to the compilation of the expression grammar.
114
115 Postfix expressions
116
117 You can supply postfix or reverse-polish notation expressions to
118 transform2() through the "rpnexpr" keyword.
119
120 The parser for "rpnexpr" emulates a stack machine, so operators will
121 expect to see their parameters on top of the stack. A stack machine
122 isn't actually used during the image transformation itself.
123
124 You can store the value at the top of the stack in a variable called
125 "foo" using "!foo" and retrieve that value again using @foo. The !foo
126 notation will pop the value from the stack.
127
128 An example equivalent to the infix expression above:
129
130 $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp'
131
132 At the end of the expression there should be a single pixel value left
133 on the stack, which is used as the output pixel.
134
135 Operators
136
137 transform2() has a fairly rich range of operators.
138
139 Each entry below includes the usage with "rpnexpr", formatted as:
140
141 operand operand ... operator -- result
142
143 If the operand or result begins with "N" it is a numeric value, if it
144 begins with "C" it is a color or pixel value.
145
146 +, *, -, /, %, **
147 multiplication, addition, subtraction, division, remainder and
148 exponentiation. Multiplication, addition and subtraction can be
149 used on color values too - though you need to be careful - adding 2
150 white values together and multiplying by 0.5 will give you gray,
151 not white.
152
153 Division by zero (or a small number) just results in a large
154 number. Modulo zero (or a small number) results in zero. % is
155 implemented using fmod() so you can use this to take a value mod a
156 floating point value.
157
158 "rpnexpr" usage:
159
160 N1 N2 + -- N
161
162 N1 N2 * -- N
163
164 N1 N2 - -- N
165
166 N1 N2 / -- N
167
168 N1 N2 ** -- N
169
170 N1 uminus -- N
171
172 sin(N), cos(N), atan2(y,x)
173 Some basic trig functions. They work in radians, so you can't just
174 use the hue values.
175
176 "rpnexpr" usage:
177
178 N sin -- N
179
180 N cos -- N
181
182 Ny Nx atan2 -- N
183
184 distance(x1, y1, x2, y2)
185 Find the distance between two points. This is handy (along with
186 atan2()) for producing circular effects.
187
188 "rpnexpr" usage:
189
190 Nx1 Ny1 Nx2 Ny2 distance -- N
191
192 sqrt(n)
193 Find the square root. I haven't had much use for this since adding
194 the distance() function.
195
196 "rpnexpr" usage:
197
198 N sqrt -- N
199
200 abs(n)
201 Find the absolute value.
202
203 "rpnexpr" usage:
204
205 N abs -- N
206
207 getp1(x,y), getp2(x,y), getp3(x, y)
208 Get the pixel at position (x,y) from the first, second or third
209 image respectively. I may add a getpn() function at some point,
210 but this prevents static checking of the instructions against the
211 number of images actually passed in.
212
213 "rpnexpr" usage:
214
215 Nx Ny getp1 -- C
216
217 Nx Ny getp2 -- C
218
219 Nx Ny getp3 -- C
220
221 value(c), hue(c), sat(c), hsv(h,s,v), hsva(h,s,v,alpha)
222 Separates a color value into it's value (brightness), hue (color)
223 and saturation elements. Use hsv() to put them back together
224 (after suitable manipulation), or hsva() to include a transparency
225 value.
226
227 "rpnexpr" usage:
228
229 C value -- N
230
231 C hue -- N
232
233 C sat -- N
234
235 Nh Ns Nv hsv -- C
236
237 Nh Ns Nv Na hsva -- C
238
239 red(c), green(c), blue(c), rgb(r,g,b), rgba(r,g,b,a)
240 Separates a color value into it's red, green and blue colors. Use
241 rgb(r,g,b) to put it back together, or rgba() to include a
242 transparency value.
243
244 "rpnexpr" usage:
245
246 C red -- N
247
248 C green -- N
249
250 C blue -- N
251
252 Nr Ng Nb rgb -- C
253
254 Nr Ng Nb Na rgba -- C
255
256 alpha(c)
257 Retrieve the alpha value from a color.
258
259 "rpnexpr" usage:
260
261 C alpha -- N
262
263 int(n)
264 Convert a value to an integer. Uses a C int cast, so it may break
265 on large values.
266
267 "rpnexpr" usage:
268
269 N int -- N
270
271 if(cond,ntrue,nfalse), if(cond,ctrue,cfalse)
272 A simple (and inefficient) if function.
273
274 "rpnexpr" usage:
275
276 Ncond N-true-result N-false-result if -- N
277
278 Ncond C-true-result C-false-result if -- C
279
280 Ncond C-true-result C-false-result ifp -- C
281
282 <=,<,==,>=,>,!=
283 Relational operators (typically used with if()). Since we're
284 working with floating point values the equalities are 'near
285 equalities' - an epsilon value is used.
286
287 N1 N2 <= -- N
288
289 N1 N2 < -- N
290
291 N1 N2 >= -- N
292
293 N1 N2 > -- N
294
295 N1 N2 == -- N
296
297 N1 N2 != -- N
298
299 &&, ||, not(n)
300 Basic logical operators.
301
302 "rpnexpr" usage:
303
304 N1 N2 and -- N
305
306 N1 N2 or -- N
307
308 N not -- N
309
310 log(n), exp(n)
311 Natural logarithm and exponential.
312
313 "rpnexpr" usage:
314
315 N log -- N
316
317 N exp -- N
318
319 det(a, b, c, d)
320 Calculate the determinant of the 2 x 2 matrix;
321
322 a b
323 c d
324
325 "rpnexpr" usage:
326
327 Na Nb Nc Nd det -- N
328
329 Constants
330
331 transform2() defines the following constants:
332
333 "pi"
334 The classical constant.
335
336 "w"
337 "h" The width and height of the output image.
338
339 "cx"
340 "cy"
341 The center of the output image.
342
343 "w"image number
344 "h"image number
345 The width and height of each of the input images, "w1" is the width
346 of the first input image and so on.
347
348 "cx"image number
349 "cy"image number
350 The center of each of the input images, ("cx1", "cy1") is the
351 center of the first input image and so on.
352
353 A few examples:
354
355 rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp'
356
357 tiles a smaller version of the input image over itself where the
358 color has a saturation over 0.7.
359
360 rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd'
361
362 tiles the input image over itself so that at the top of the image
363 the full-size image is at full strength and at the bottom the
364 tiling is most visible.
365
366 rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp'
367
368 replace pixels that are white or almost white with a palish blue
369
370 rpnexpr=>'x 35 % 10 * y 45 % 8 * getp1 !pat x y getp1 !pix @pix sat 0.2 lt @pix value 0.9 gt and @pix @pat @pix value 2 / 0.5 + pmult ifp'
371
372 Tiles the input image over it self where the image isn't white or
373 almost white.
374
375 rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
376
377 Produces a spiral.
378
379 rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
380
381 A spiral built on top of a color wheel.
382
383 For details on expression parsing see Imager::Expr. For details on the
384 virtual machine used to transform the images, see Imager::regmach.
385
386 # generate a colorful spiral
387 # requires that Parse::RecDescent be installed
388 my $newimg = Imager::transform2({
389 width => 160, height=>160,
390 expr => <<EOS
391 dist = distance(x, y, w/2, h/2);
392 angle = atan2(y-h/2, x-w/2);
393 angle2 = (dist / 10 + angle) % ( 2 * pi );
394 return hsv(angle*180/pi, 1, (sin(angle2)+1)/2);
395 EOS
396 });
397
398 # replace green portions of an image with another image
399 my $newimg = Imager::transform2({
400 rpnexpr => <<EOS
401 x y getp2 !pat # used to replace green portions
402 x y getp1 !pix # source with "green screen"
403 @pix red 10 lt @pix blue 10 lt && # low blue and red
404 @pix green 254 gt && # and high green
405 @pat @pix ifp
406 EOS
407 }, $source, $background);
408
409 Matrix Transformations
410 matrix_transform()
411 Rather than having to write code in a little language, you can use
412 a matrix to perform affine transformations, using the
413 matrix_transform() method:
414
415 my $newimg = $img->matrix_transform(matrix=>[ -1, 0, $img->getwidth-1,
416 0, 1, 0,
417 0, 0, 1 ]);
418
419 By default the output image will be the same size as the input
420 image, but you can supply the "xsize" and "ysize" parameters to
421 change the size.
422
423 Rather than building matrices by hand you can use the
424 Imager::Matrix2d module to build the matrices. This class has
425 methods to allow you to scale, shear, rotate, translate and
426 reflect, and you can combine these with an overloaded
427 multiplication operator.
428
429 WARNING: the matrix you provide in the matrix operator transforms
430 the co-ordinates within the destination image to the co-ordinates
431 within the source image. This can be confusing.
432
433 You can also supply a "back" argument which acts as a background
434 color for the areas of the image with no samples available (outside
435 the rectangle of the source image.) This can be either an
436 Imager::Color or Imager::Color::Float object. This is not mixed
437 transparent pixels in the middle of the source image, it is only
438 used for pixels where there is no corresponding pixel in the source
439 image.
440
442 Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson
443
444
445
446perl v5.38.0 2023-07-20 Imager::Engines(3)