1Imager::Engines(3)    User Contributed Perl Documentation   Imager::Engines(3)
2
3
4

NAME

6       Imager::Engines - Programmable transformation operations
7

SYNOPSIS

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

DESCRIPTION

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

AUTHOR

442       Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson
443
444
445
446perl v5.38.0                      2023-07-20                Imager::Engines(3)
Impressum