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