1Imager::Cookbook(3) User Contributed Perl Documentation Imager::Cookbook(3)
2
3
4
6 Imager::Cookbook - recipes working with Imager
7
9 Various simple and not so simple ways to do things with Imager.
10
12 This is described in detail in Imager::Files.
13
14 Reading an image from a file
15 my $image = Imager->new;
16
17 $image->read(file=>$filename) or die $image->errstr;
18
19 See Imager::Files.
20
21 Writing an image to a file
22 $image->write(file=>$filename) or die $image->errstr;
23
24 Write an animated GIF
25 # build an array of images to use in the gif
26 my @images;
27 # synthesize the images or read them from files, it doesn't matter
28 ...
29
30 # write the gif
31 Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
32 or die Imager->errstr;
33
34 See "Writing an animated GIF" in Imager::Files for a more detailed
35 example.
36
37 Reading multiple images from one file
38 Some formats, like GIF and TIFF support multiple images per file. Use
39 the read_multi() method to read them:
40
41 my @images = Imager->read_multi(file=>$filename)
42 or die Imager->errstr;
43
44 Converting from one file format to another
45 This is as simple as reading the original file and writing the new
46 file, for single images:
47
48 my $image = Imager->new;
49 # Imager auto-detects the input file type
50 $image->read(file => $input_filename)
51 or die $image->errstr;
52 # Imager derives the output file format from the filename
53 $image->write(file => $output_filename)
54 or die $image->errstr;
55
56 # or you can supply a type parameter:
57 $image->write(file => $output_filename, type => 'gif')
58 or die $image->errstr;
59
60 The main issue that can occur with this is if the input file has
61 transparency and the output file format doesn't support that. This can
62 be a problem when converting from GIF files to JPEG files for example.
63
64 To work around that you can compose the source image onto a background
65 color:
66
67 if ($image->getchannels == 4 or $image->getchannels == 2) {
68 my $back = Imager->new(xsize => $image->getwidth,
69 ysize => $image->getheight);
70 # grey background for grayscale images, red for color
71 my $back_color = $image->getchannels == 2 ? [ 128 ] : 'red';
72 $back->box(filled => 1, color => $back_color);
73 $back->rubthrough(src => $image);
74 $image = $back;
75 }
76 # now we can write safely to jpeg or pnm
77
78 Some formats support multiple files, so if you want to convert from say
79 TIFF to JPEG, you'll need multiple output files:
80
81 my @images = Imager->read_multi(file => 'input.tif')
82 or die Imager->errstr;
83 my $index = 1;
84 for my $image (@images) {
85 $image->write(file => sprintf('output%02d.jpg', $index++))
86 or die $image->errstr;
87 }
88
89 Transparent PNG
90 To save to a transparent PNG (or GIF or TIFF) you need to start with an
91 image with transparency.
92
93 To make a transparent image, create an image object with 2 or 4
94 channels:
95
96 # RGB with alpha channel
97 my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
98
99 # Gray with alpha channel
100 my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
101
102 By default, the created image will be transparent.
103
104 Otherwise, if you have an existing image file with transparency, simply
105 read it, and the transparency will be preserved.
106
108 Creating an image
109 To create a simple RGB image, supply the image width and height to the
110 new() method:
111
112 my $rgb = Imager->new(xsize=>$width, ysize=>$height);
113
114 If you also want an alpha channel:
115
116 my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
117
118 To make a gray-scale image:
119
120 my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
121
122 and a gray-scale image with an alpha channel:
123
124 my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
125
126 When a new image is created this way all samples are set to zero -
127 black for 1 or 3 channel images, transparent black for 2 or 4 channel
128 images.
129
130 You can also create paletted images and images with more than 8-bits
131 per channel, see Imager::ImageTypes for more details.
132
133 Setting the background of a new image
134 To set the background of a new image to a solid color, use the box()
135 method with no limits, and "filled=>1":
136
137 $image->box(filled=>1, color=>$color);
138
139 As always, a color can be specified as an Imager::Color object:
140
141 my $white = Imager::Color->new(255, 255, 255);
142 $image->box(filled=>1, color=>$white);
143
144 or you supply any single scalar that Imager::Color's new() method
145 accepts as a color description:
146
147 $image->box(filled=>1, color=>'white');
148 $image->box(filled=>1, color=>'#FF0000');
149 $image->box(filled=>1, color=>[ 255, 255, 255 ]);
150
151 You can also fill the image with a fill object:
152
153 use Imager::Fill;
154 # create the fill object
155 my $fill = Imager::Fill->new(hatch=>'check1x1')
156 $image->box(fill=>$fill);
157
158 # let Imager create one automatically
159 $image->box(fill=>{ hatch=>'check1x1' });
160
161 See Imager::Fill for information on Imager's fill objects.
162
164 As with any CGI script it's up to you to validate data and set limits
165 on any parameters supplied to Imager.
166
167 For example, if you allow the caller to set the size of an output image
168 you should limit the size to prevent the client from specifying an
169 image size that will consume all available memory.
170
171 This is beside any any other controls you need over access to data.
172
173 See CGI for a module useful for processing CGI submitted data.
174
175 Returning an image from a CGI script
176 This is similar to writing to a file, but you also need to supply the
177 information needed by the web browser to identify the file format:
178
179 my $img = ....; # create the image and generate the contents
180 ++$|; # make sure the content type isn't buffered
181 print "Content-Type: image/png\n\n";
182 binmode STDOUT;
183 $img->write(fd=>fileno(STDOUT), type=>'png')
184 or die $img->errstr;
185
186 You need to set the Content-Type header depending on the file format
187 you send to the web browser.
188
189 If you want to supply a content-length header, write the image to a
190 scalar as a buffer:
191
192 my $img = ....; # create the image and generate the contents
193 my $data;
194 $img->write(type=>'png', data=>\$data)
195 or die $img->errstr;
196 print "Content-Type: image/png\n";
197 print "Content-Length: ",length($data),"\n\n";
198 binmode STDOUT;
199 print $data;
200
201 See "samples/samp-scale.cgi" and "samples/samp-image.cgi" for a couple
202 of simple examples of producing an image from CGI.
203
204 Inserting a CGI image in a page
205 There's occasionally confusion on how to display an image generated by
206 Imager in a page generated by a CGI.
207
208 Your web browser handles this process as two requests, one for the HTML
209 page, and another for the image itself.
210
211 Each request needs to perform validation since an attacker can control
212 the values supplied to both requests.
213
214 How you make the data available to the image generation code depends on
215 your application.
216
217 See "samples/samp-form.cgi" and "samples/samp-image.cgi" in the Imager
218 distribution for one approach. The POD in "samp-form.cgi" also
219 discusses some of the issues involved.
220
221 Parsing an image posted via CGI
222 "WARNING": file format attacks have become a common attack vector, make
223 sure you have up to date image file format libraries, otherwise trying
224 to parse uploaded files, whether with Imager or some other tool, may
225 result in a remote attacker being able to run their own code on your
226 system.
227
228 If your HTML form uses the correct magic, it can upload files to your
229 CGI script, in particular, you need to use " method="post" " and
230 "enctype="multipart/form-data"" in the "form" tag, and use
231 "type="file"" in the "input", for example:
232
233 <form action="/cgi-bin/yourprogram" method="post"
234 enctype="multipart/form-data">
235 <input type="file" name="myimage" />
236 <input type="submit value="Upload Image" />
237 </form>
238
239 To process the form:
240
241 1. first check that the user supplied a file
242
243 2. get the file handle
244
245 3. have Imager read the image
246
247 # returns the client's name for the file, don't open this locally
248 my $cgi = CGI->new;
249 # 1. check the user supplied a file
250 my $filename = $cgi->param('myimage');
251 if ($filename) {
252 # 2. get the file handle
253 my $fh = $cgi->upload('myimage');
254 if ($fh) {
255 binmode $fh;
256
257 # 3. have Imager read the image
258 my $img = Imager->new;
259 if ($img->read(fh=>$fh)) {
260 # we can now process the image
261 }
262 }
263 # else, you probably have an incorrect form or input tag
264 }
265 # else, the user didn't select a file
266
267 See "samples/samp-scale.cgi" and "samples/samp-tags.cgi" in the Imager
268 distribution for example code.
269
270 You may also want to set limits on the size of the image read, using
271 Imager's "set_file_limits" method, documented in "set_file_limits()" in
272 Imager::Files. For example:
273
274 # limit to 10 million bytes of memory usage
275 Imager->set_file_limits(bytes => 10_000_000);
276
277 # limit to 1024 x 1024
278 Imager->set_file_limits(width => 1024, height => 1024);
279
281 Adding a border to an image
282 First make a new image with space for the border:
283
284 my $border_width = ...;
285 my $border_height = ...;
286 my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
287 ysize => $source->getheight() + 2 * $border_height,
288 bits => $source->bits,
289 channels => $source->getchannels);
290
291 Then paste the source image into the new image:
292
293 $out->paste(left => $border_width,
294 top => $border_height,
295 img => $source);
296
297 Whether you draw the border before or after pasting the original image
298 depends on whether you want the border to overlap the image, for
299 example a semi-transparent border drawn after pasting the source image
300 could overlap the edge without hiding it.
301
302 If you want a solid border you could just fill the image before pasting
303 the source for simplicity:
304
305 $out->box(filled=>1, color=>'red');
306 $out->paste(left => $border_width,
307 top => $border_height,
308 img => $source);
309
311 Drawing text
312 Aligning text
313 Measuring text
314 Word wrapping text
315 Shearing (slanting) or Rotating text
316 This requires that you have Imager installed with FreeType 2.x support
317 installed, and that the font be created using the FreeType 2.x driver,
318 for example:
319
320 my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
321
322 First you need a transformation matrix, for shearing that could be:
323
324 my $angle_in_radians = ...;
325 my $tan_angle = sin($angle_rads) / cos($angle_rads);
326 # shear horizontally, supply this as y instead to do it vertically
327 my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
328
329 For rotation that would be:
330
331 my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
332
333 or:
334
335 my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
336
337 Feed that to the font object:
338
339 $font->transform(matrix => $matrix);
340
341 and draw the text as normal:
342
343 $image->string(string => $text,
344 x => $where_x,
345 y => $where_y,
346 color => $color,
347 font => $font);
348
349 See samples/slant_text.pl for a comprehensive example, including
350 calculating the transformed bounding box to create an image to fit the
351 transformed text into.
352
354 Shearing an image
355 Convert to gray-scale
356 To convert an RGB image to a gray-scale image, use the convert method:
357
358 my $grey = $image->convert(preset => 'gray');
359
360 convert() returns a new image.
361
362 See: "Color transformations" in Imager::Transformations
363
365 Image format
366 When Imager reads a file it does a magic number check to determine the
367 file type, so "foo.png" could actually be a GIF image, and Imager will
368 read it anyway.
369
370 You can check the actual format of the image by looking at the
371 "i_format" tag.
372
373 my $format = $image->tags(name=>'i_format');
374
375 Image spatial resolution
376 Most image file formats store information about the physical size of
377 the pixels, though in some cases that information isn't useful.
378
379 Imager stores this information in the tags "i_xres" and "i_yres", and
380 this is always stored in dots per inch.
381
382 Some formats, including TIFF and JPEG allow you to change the units
383 spatial resolution information is stored in, if you set the tag that
384 changes this the Imager will convert "i_xres" and "i_yres" to those
385 units when it writes the file.
386
387 For example to set the resolution to 300 dpi:
388
389 $image->settag(name => 'i_xres', value => 300);
390 $image->settag(name => 'i_yres', value => 300);
391
392 If you want the file format to store the resolution in some other unit,
393 for example you can write a TIFF file that stores the resolution in
394 pixels per centimeter, you would do:
395
396 # 150 pixels/cm
397 $image->settag(name => 'i_xres', value => 150 * 2.54);
398 $image->settag(name => 'i_yres', value => 150 * 2.54);
399 $image->settag(name => 'tiff_resolutionunit', value => 3);
400
401 Keywords: DPI
402
404 Tony Cook <tony@develop-help.com>
405
407 Imager, Imager::Files, Imager::Draw.
408
409
410
411perl v5.12.3 2011-08-28 Imager::Cookbook(3)