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