]> git.imager.perl.org - imager.git/blob - lib/Imager/Transformations.pod
- added samp-form.cgi and samp-image.cgi to the samples directory to
[imager.git] / lib / Imager / Transformations.pod
1 =head1 NAME
2
3 Imager::Transformations - Simple transformations of one image into another.
4
5 =head1 SYNOPSIS
6
7   use Imager;
8
9   $newimg = $img->copy();
10
11   $newimg = $img->scale(xpixels=>400);
12   $newimg = $img->scale(xpixels=>400, ypixels=>400);
13   $newimg = $img->scale(xpixels=>400, ypixels=>400, type=>'min');
14   $newimg = $img->scale(scalefactor=>0.25);
15
16   $newimg = $img->scaleX(pixels=>400);
17   $newimg = $img->scaleX(scalefactor=>0.25);
18   $newimg = $img->scaleY(pixels=>400);
19   $newimg = $img->scaleY(scalefactor=>0.25);
20
21   $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100); 
22   $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
23
24   $dest->paste(left=>40,top=>20,img=>$logo);
25
26   $img->rubthrough(src=>$srcimage,tx=>30, ty=>50);
27   $img->rubthrough(src=>$srcimage,tx=>30, ty=>50,
28                    src_minx=>20, src_miny=>30,
29                    src_maxx=>20, src_maxy=>30);
30
31
32   $img->flip(dir=>"h");       # horizontal flip
33   $img->flip(dir=>"vh");      # vertical and horizontal flip
34   $newimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
35
36   my $rot20 = $img->rotate(degrees=>20);
37   my $rotpi4 = $img->rotate(radians=>3.14159265/4);
38
39
40   # Convert image to gray
41   $new = $img->convert(preset=>'grey');          
42
43   # Swap red/green channel  
44   $new = $img->convert(matrix=>[ [ 0, 1, 0 ],
45                                  [ 1, 0, 0 ],
46                                  [ 0, 0, 1 ] ]);
47
48   # limit the range of red channel from 0..255 to 0..127
49   @map = map { int( $_/2 } 0..255;
50   $img->map( red=>\@map );
51
52   # Apply a Gamma of 1.4
53   my $gamma = 1.4;
54   my @map = map { int( 0.5 + 255*($_/255)**$gamma ) } 0..255;
55   $img->map(all=>\@map);  # inplace conversion
56
57 =head1 DESCRIPTION
58
59 The methods described in Imager::Transformations fall into two categories.
60 Either they take an existing image and modify it in place, or they 
61 return a modified copy.
62
63 Functions that modify inplace are C<flip()>, C<paste()> and
64 C<rubthrough()>.  If the original is to be left intact it's possible
65 to make a copy and alter the copy:
66
67   $flipped = $img->copy()->flip(dir=>'h');
68
69 =head2 Image copying/resizing/cropping/rotating
70
71 A list of the transformations that do not alter the source image follows:
72
73 =over
74
75 =item copy
76
77 To create a copy of an image use the C<copy()> method.  This is usefull
78 if you want to keep an original after doing something that changes the image.
79
80   $newimg = $orig->copy();
81
82 =item scale
83
84 =item scaleX
85
86 =item scaleY
87
88 To scale an image so porportions are maintained use the
89 C<$img-E<gt>scale()> method.  if you give either a xpixels or ypixels
90 parameter they will determine the width or height respectively.  If
91 both are given the one resulting in a larger image is used, unless you
92 set the C<type> parameter to C<'min'>.  example: C<$img> is 700 pixels
93 wide and 500 pixels tall.
94
95   $newimg = $img->scale(xpixels=>400); # 400x285
96   $newimg = $img->scale(ypixels=>400); # 560x400
97
98   $newimg = $img->scale(xpixels=>400,ypixels=>400); # 560x400
99   $newimg = $img->scale(xpixels=>400,ypixels=>400,type=>'min'); # 400x285
100
101   $newimg = $img->scale(scalefactor=>0.25); 175x125 
102   $newimg = $img->scale(); # 350x250
103
104 if you want to create low quality previews of images you can pass
105 C<qtype=E<gt>'preview'> to scale and it will use nearest neighbor
106 sampling instead of filtering. It is much faster but also generates
107 worse looking images - especially if the original has a lot of sharp
108 variations and the scaled image is by more than 3-5 times smaller than
109 the original.
110
111 If you need to scale images per axis it is best to do it simply by
112 calling scaleX() or scaleY().  You can pass either 'scalefactor' or
113 'pixels' to both functions.
114
115 scaleX() will scale along the X dimension, changing the width of the
116 image:
117
118   $newimg = $img->scaleX(pixels=>400); # 400x500
119   $newimg = $img->scaleX(scalefactor=>0.25) # 175x500
120
121 scaleY() will scale along the Y dimension, changing the height of the
122 image:
123
124   $newimg = $img->scaleY(pixels=>400); # 700x400
125   $newimg = $img->scaleY(scalefactor=>0.25) # 700x125
126
127 =item crop
128
129 Another way to resize an image is to crop it.  The parameters to
130 crop are the edges of the area that you want in the returned image,
131 where the right and bottom edges are non-inclusive.  If a parameter is
132 omitted a default is used instead.
133
134 The possible parameters are:
135
136 =over
137
138 =item *
139
140 C<left> - the left edge of the area to be cropped.  Default: 0
141
142 =item *
143
144 C<top> - the top edge of the area to be cropped.  Default: 0
145
146 =item *
147
148 C<right> - the right edge of the area to be cropped.  Default: right
149 edge of image.
150
151 =item *
152
153 C<bottom> - the bottom edge of the area to be cropped.  Default:
154 bottom edge of image.
155
156 =item *
157
158 C<width> - width of the crop area.  Ignored if both C<left> and C<right> are
159 supplied.  Centered on the image if neither C<left> nor C<right> are
160 supplied.
161
162 =item *
163
164 C<height> - height of the crop area.  Ignored if both C<top> and
165 C<bottom> are supplied.  Centered on the image if neither C<top> nor
166 C<bottom> are supplied.
167
168 =back
169
170 For example:
171
172   # these produce the same image
173   $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100); 
174   $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
175   $newimg = $img->crop(right=>100, bottom=>100, width=>50, height=>90);
176
177   # and the following produce the same image
178   $newimg = $img->crop(left=>50, right=>100);
179   $newimg = $img->crop(left=>50, right=>100, top=>0, 
180                        bottom=>$img->getheight);
181
182   # grab the top left corner of the image
183   $newimg = $img->crop(right=>50, bottom=>50);
184
185 You can also specify width and height parameters which will produce a
186 new image cropped from the center of the input image, with the given
187 width and height.
188
189   $newimg = $img->crop(width=>50, height=>50);
190
191 If you supply C<left>, C<width> and C<right> values, the C<right>
192 value will be ignored.  If you supply C<top>, C<height> and C<bottom>
193 values, the C<bottom> value will be ignored.
194
195 The edges of the cropped area default to the edges of the source
196 image, for example:
197
198   # a vertical bar from the middle from top to bottom
199   $newimg = $img->crop(width=>50);
200
201   # the right half
202   $newimg = $img->crop(left=>$img->getwidth() / 2);
203
204 If the resulting image would have zero width or height then crop()
205 returns false and $img->errstr is an appropriate error message.
206
207 =item rotate
208
209 Use the rotate() method to rotate an image.  This method will return a
210 new, rotated image.
211
212 To rotate by an exact amount in degrees or radians, use the 'degrees'
213 or 'radians' parameter:
214
215   my $rot20 = $img->rotate(degrees=>20);
216   my $rotpi4 = $img->rotate(radians=>3.14159265/4);
217
218 Exact image rotation uses the same underlying transformation engine as
219 the matrix_transform() method (see Imager::Engines).
220
221 You can also supply a C<back> argument which acts as a background
222 color for the areas of the image with no samples available (outside
223 the rectangle of the source image.)  This can be either an
224 Imager::Color or Imager::Color::Float object.  This is B<not> mixed
225 transparent pixels in the middle of the source image, it is B<only>
226 used for pixels where there is no corresponding pixel in the source
227 image.
228
229 To rotate in steps of 90 degrees, use the 'right' parameter:
230
231   my $rotated = $img->rotate(right=>270);
232
233 Rotations are clockwise for positive values.
234
235
236 =back
237
238
239 =head2 Image pasting/flipping/
240
241 A list of the transformations that alter the source image follows:
242
243 =over
244
245 =item paste
246
247
248 To copy an image to onto another image use the C<paste()> method.
249
250   $dest->paste(left=>40,top=>20,img=>$logo);
251
252 That copies the entire C<$logo> image onto the C<$dest> image so that the
253 upper left corner of the C<$logo> image is at (40,20).
254
255
256 =item rubthrough
257
258 A more complicated way of blending images is where one image is
259 put 'over' the other with a certain amount of opaqueness.  The
260 method that does this is rubthrough.
261
262   $img->rubthrough(src=>$overlay,
263                    tx=>30,       ty=>50,
264                    src_minx=>20, src_miny=>30,
265                    src_maxx=>20, src_maxy=>30);
266
267 That will take the sub image defined by I<$overlay> and
268 I<[src_minx,src_maxx)[src_miny,src_maxy)> and overlay it on top of
269 I<$img> with the upper left corner at (30,50).  You can rub 2 or 4
270 channel images onto a 3 channel image, or a 2 channel image onto a 1
271 channel image.  The last channel is used as an alpha channel.  To add
272 an alpha channel to an image see I<convert()>.
273
274
275 =item flip
276
277 An inplace horizontal or vertical flip is possible by calling the
278 C<flip()> method.  If the original is to be preserved it's possible to
279 make a copy first.  The only parameter it takes is the C<dir>
280 parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
281
282   $img->flip(dir=>"h");       # horizontal flip
283   $img->flip(dir=>"vh");      # vertical and horizontal flip
284   $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
285
286 =back
287
288
289
290
291 =head2 Color transformations
292
293 You can use the convert method to transform the color space of an
294 image using a matrix.  For ease of use some presets are provided.
295
296 The convert method can be used to:
297
298 =over
299
300 =item *
301
302 convert an RGB or RGBA image to grayscale.
303
304 =item *
305
306 convert a grayscale image to RGB.
307
308 =item *
309
310 extract a single channel from an image.
311
312 =item *
313
314 set a given channel to a particular value (or from another channel)
315
316 =back
317
318 The currently defined presets are:
319
320 =over
321
322 =item gray
323
324 =item grey
325
326 converts an RGBA image into a grayscale image with alpha channel, or
327 an RGB image into a grayscale image without an alpha channel.
328
329 This weights the RGB channels at 22.2%, 70.7% and 7.1% respectively.
330
331 =item noalpha
332
333 removes the alpha channel from a 2 or 4 channel image.  An identity
334 for other images.
335
336 =item red
337
338 =item channel0
339
340 extracts the first channel of the image into a single channel image
341
342 =item green
343
344 =item channel1
345
346 extracts the second channel of the image into a single channel image
347
348 =item blue
349
350 =item channel2
351
352 extracts the third channel of the image into a single channel image
353
354 =item alpha
355
356 extracts the alpha channel of the image into a single channel image.
357
358 If the image has 1 or 3 channels (assumed to be grayscale of RGB) then
359 the resulting image will be all white.
360
361 =item rgb
362
363 converts a grayscale image to RGB, preserving the alpha channel if any
364
365 =item addalpha
366
367 adds an alpha channel to a grayscale or RGB image.  Preserves an
368 existing alpha channel for a 2 or 4 channel image.
369
370 =back
371
372 For example, to convert an RGB image into a greyscale image:
373
374   $new = $img->convert(preset=>'grey'); # or gray
375
376 or to convert a grayscale image to an RGB image:
377
378   $new = $img->convert(preset=>'rgb');
379
380 The presets aren't necessary simple constants in the code, some are
381 generated based on the number of channels in the input image.
382
383 If you want to perform some other colour transformation, you can use
384 the 'matrix' parameter.
385
386 For each output pixel the following matrix multiplication is done:
387
388   | channel[0] |   | $c00, ...,  $c0k |   | inchannel[0] |
389   |    ...     | = |       ...        | x |     ...      |
390   | channel[k] |   | $ck0, ...,  $ckk |   | inchannel[k] |
391                                                           1
392 Where C<k = $img-E<gt>getchannels()-1>.
393
394 So if you want to swap the red and green channels on a 3 channel image:
395
396   $new = $img->convert(matrix=>[ [ 0, 1, 0 ],
397                                  [ 1, 0, 0 ],
398                                  [ 0, 0, 1 ] ]);
399
400 or to convert a 3 channel image to greyscale using equal weightings:
401
402   $new = $img->convert(matrix=>[ [ 0.333, 0.333, 0.334 ] ])
403
404
405 =head2 Color Mappings
406
407 You can use the map method to map the values of each channel of an
408 image independently using a list of lookup tables.  It's important to
409 realize that the modification is made inplace.  The function simply
410 returns the input image again or undef on failure.
411
412 Each channel is mapped independently through a lookup table with 256
413 entries.  The elements in the table should not be less than 0 and not
414 greater than 255.  If they are out of the 0..255 range they are
415 clamped to the range.  If a table does not contain 256 entries it is
416 silently ignored.
417
418 Single channels can mapped by specifying their name and the mapping
419 table.  The channel names are C<red>, C<green>, C<blue>, C<alpha>.
420
421   @map = map { int( $_/2 } 0..255;
422   $img->map( red=>\@map );
423
424 It is also possible to specify a single map that is applied to all
425 channels, alpha channel included.  For example this applies a gamma
426 correction with a gamma of 1.4 to the input image.
427
428   $gamma = 1.4;
429   @map = map { int( 0.5 + 255*($_/255)**$gamma ) } 0..255;
430   $img->map(all=> \@map);
431
432 The C<all> map is used as a default channel, if no other map is
433 specified for a channel then the C<all> map is used instead.  If we
434 had not wanted to apply gamma to the alpha channel we would have used:
435
436   $img->map(all=> \@map, alpha=>[]);
437
438 Since C<[]> contains fewer than 256 element the gamma channel is
439 unaffected.
440
441 It is also possible to simply specify an array of maps that are
442 applied to the images in the rgba order.  For example to apply
443 maps to the C<red> and C<blue> channels one would use:
444
445   $img->map(maps=>[\@redmap, [], \@bluemap]);
446
447 =cut