3 Imager::Cookbook - recipes working with Imager
7 Various simple and not so simple ways to do things with Imager.
11 This is described in detail in L<Imager::Files>.
13 =head2 Reading an image from a file
15 my $image = Imager->new;
17 $image->read(file=>$filename) or die $image->errstr;
21 =head2 Writing an image to a file
23 $image->write(file=>$filename) or die $image->errstr;
25 =head2 Write an animated GIF
27 # build an array of images to use in the gif
29 # synthesize the images or read them from files, it doesn't matter
33 Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
34 or die Imager->errstr;
36 See L<Imager::Files/"Writing an animated GIF"> for a more detailed
39 =head2 Reading multiple images from one file
41 Some formats, like GIF and TIFF support multiple images per file. Use
42 the L<read_multi()|Imager::Files> method to read them:
44 my @images = Imager->read_multi(file=>$filename)
45 or die Imager->errstr;
47 =head2 Converting from one file format to another
49 This is as simple as reading the original file and writing the new
50 file, for single images:
52 my $image = Imager->new;
53 # Imager auto-detects the input file type
54 $image->read(file => $input_filename)
55 or die $image->errstr;
56 # Imager derives the output file format from the filename
57 $image->write(file => $output_filename)
58 or die $image->errstr;
60 # or you can supply a type parameter:
61 $image->write(file => $output_filename, type => 'gif')
62 or die $image->errstr;
64 The main issue that can occur with this is if the input file has
65 transparency and the output file format doesn't support that. This
66 can be a problem when converting from GIF files to JPEG files for
69 To work around that you can compose the source image onto a background
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);
81 # now we can write safely to jpeg or pnm
83 Some formats support multiple files, so if you want to convert from
84 say TIFF to JPEG, you'll need multiple output files:
86 my @images = Imager->read_multi(file => 'input.tif')
87 or die Imager->errstr;
89 for my $image (@images) {
90 $image->write(file => sprintf('output%02d.jpg', $index++))
91 or die $image->errstr;
94 =head2 Transparent PNG
96 To save to a transparent PNG (or GIF or TIFF) you need to start with
97 an image with transparency.
99 To make a transparent image, create an image object with 2 or 4
102 # RGB with alpha channel
103 my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
105 # Gray with alpha channel
106 my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
108 By default, the created image will be transparent.
110 Otherwise, if you have an existing image file with transparency,
111 simply read it, and the transparency will be preserved.
113 =head1 IMAGE SYNTHESIS
115 =head2 Creating an image
117 To create a simple RGB image, supply the image width and height to the
120 my $rgb = Imager->new(xsize=>$width, ysize=>$height);
122 If you also want an alpha channel:
124 my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
126 To make a gray-scale image:
128 my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
130 and a gray-scale image with an alpha channel:
132 my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
134 When a new image is created this way all samples are set to zero -
135 black for 1 or 3 channel images, transparent black for 2 or 4 channel
138 You can also create paletted images and images with more than 8-bits
139 per channel, see L<Imager::ImageTypes> for more details.
141 =head2 Setting the background of a new image
143 To set the background of a new image to a solid color, use the box()
144 method with no limits, and C<< filled=>1 >>:
146 $image->box(filled=>1, color=>$color);
148 As always, a color can be specified as an L<Imager::Color> object:
150 my $white = Imager::Color->new(255, 255, 255);
151 $image->box(filled=>1, color=>$white);
153 or you supply any single scalar that Imager::Color's new() method
154 accepts as a color description:
156 $image->box(filled=>1, color=>'white');
157 $image->box(filled=>1, color=>'#FF0000');
158 $image->box(filled=>1, color=>[ 255, 255, 255 ]);
160 You can also fill the image with a fill object:
163 # create the fill object
164 my $fill = Imager::Fill->new(hatch=>'check1x1')
165 $image->box(fill=>$fill);
167 # let Imager create one automatically
168 $image->box(fill=>{ hatch=>'check1x1' });
170 See L<Imager::Fill> for information on Imager's fill objects.
172 =head1 WORLD WIDE WEB
174 As with any CGI script it's up to you to validate data and set limits
175 on any parameters supplied to Imager.
177 For example, if you allow the caller to set the size of an output
178 image you should limit the size to prevent the client from specifying
179 an image size that will consume all available memory.
181 This is beside any any other controls you need over access to data.
183 See L<CGI> for a module useful for processing CGI submitted data.
185 =head2 Returning an image from a CGI script
187 This is similar to writing to a file, but you also need to supply the
188 information needed by the web browser to identify the file format:
190 my $img = ....; # create the image and generate the contents
191 ++$|; # make sure the content type isn't buffered
192 print "Content-Type: image/png\n\n";
194 $img->write(fd=>fileno(STDOUT), type=>'png')
197 You need to set the Content-Type header depending on the file format
198 you send to the web browser.
200 If you want to supply a content-length header, write the image to a
203 my $img = ....; # create the image and generate the contents
205 $img->write(type=>'png', data=>\$data)
207 print "Content-Type: image/png\n";
208 print "Content-Length: ",length($data),"\n\n";
212 See C<samples/samp-scale.cgi> and C<samples/samp-image.cgi> for a
213 couple of simple examples of producing an image from CGI.
215 =head2 Inserting a CGI image in a page
217 There's occasionally confusion on how to display an image generated by
218 Imager in a page generated by a CGI.
220 Your web browser handles this process as two requests, one for the
221 HTML page, and another for the image itself.
223 Each request needs to perform validation since an attacker can control
224 the values supplied to both requests.
226 How you make the data available to the image generation code depends
229 See C<samples/samp-form.cgi> and C<samples/samp-image.cgi> in the
230 Imager distribution for one approach. The POD in C<samp-form.cgi>
231 also discusses some of the issues involved.
233 =head2 Parsing an image posted via CGI
235 C<WARNING>: file format attacks have become a common attack vector,
236 make sure you have up to date image file format libraries, otherwise
237 trying to parse uploaded files, whether with Imager or some other
238 tool, may result in a remote attacker being able to run their own code
241 If your HTML form uses the correct magic, it can upload files to your
242 CGI script, in particular, you need to use C< method="post" > and
243 C<enctype="multipart/form-data"> in the C<form> tag, and use
244 C<type="file"> in the C<input>, for example:
246 <form action="/cgi-bin/yourprogram" method="post"
247 enctype="multipart/form-data">
248 <input type="file" name="myimage" />
249 <input type="submit value="Upload Image" />
258 first check that the user supplied a file
266 have Imager read the image
270 # returns the client's name for the file, don't open this locally
272 # 1. check the user supplied a file
273 my $filename = $cgi->param('myimage');
275 # 2. get the file handle
276 my $fh = $cgi->upload('myimage');
280 # 3. have Imager read the image
281 my $img = Imager->new;
282 if ($img->read(fh=>$fh)) {
283 # we can now process the image
286 # else, you probably have an incorrect form or input tag
288 # else, the user didn't select a file
290 See C<samples/samp-scale.cgi> and C<samples/samp-tags.cgi> in the
291 Imager distribution for example code.
293 You may also want to set limits on the size of the image read, using
294 Imager's C<set_file_limits> method, documented in
295 L<Imager::Files/set_file_limits>. For example:
297 # limit to 10 million bytes of memory usage
298 Imager->set_file_limits(bytes => 10_000_000);
300 # limit to 1024 x 1024
301 Imager->set_file_limits(width => 1024, height => 1024);
305 =head2 Adding a border to an image
307 First make a new image with space for the border:
309 my $border_width = ...;
310 my $border_height = ...;
311 my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
312 ysize => $source->getheight() + 2 * $border_height,
313 bits => $source->bits,
314 channels => $source->getchannels);
316 Then paste the source image into the new image:
318 $out->paste(left => $border_width,
319 top => $border_height,
322 Whether you draw the border before or after pasting the original image
323 depends on whether you want the border to overlap the image, for
324 example a semi-transparent border drawn after pasting the source image
325 could overlap the edge without hiding it.
327 If you want a solid border you could just fill the image before
328 pasting the source for simplicity:
330 $out->box(filled=>1, color=>'red');
331 $out->paste(left => $border_width,
332 top => $border_height,
342 =head2 Measuring text
344 =head2 Word wrapping text
346 =head2 Shearing (slanting) or Rotating text
348 This requires that you have Imager installed with FreeType 2.x support
349 installed, and that the font be created using the FreeType 2.x driver,
352 my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
354 First you need a transformation matrix, for shearing that could be:
356 my $angle_in_radians = ...;
357 my $tan_angle = sin($angle_rads) / cos($angle_rads);
358 # shear horizontally, supply this as y instead to do it vertically
359 my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
361 For rotation that would be:
363 my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
367 my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
369 Feed that to the font object:
371 $font->transform(matrix => $matrix);
373 and draw the text as normal:
375 $image->string(string => $text,
381 See samples/slant_text.pl for a comprehensive example, including
382 calculating the transformed bounding box to create an image to fit the
383 transformed text into.
385 =head1 IMAGE TRANSFORMATION
387 =head2 Shearing an image
389 =head2 Convert to gray-scale
391 To convert an RGB image to a gray-scale image, use the convert method:
393 my $grey = $image->convert(preset => 'gray');
395 convert() returns a new image.
397 See: L<Imager::Transformations/"Color transformations">
403 When Imager reads a file it does a magic number check to determine the
404 file type, so C<foo.png> could actually be a GIF image, and Imager
407 You can check the actual format of the image by looking at the
410 my $format = $image->tags(name=>'i_format');
412 =head2 Image spatial resolution
414 Most image file formats store information about the physical size of
415 the pixels, though in some cases that information isn't useful.
417 Imager stores this information in the tags C<i_xres> and C<i_yres>,
418 and this is always stored in dots per inch.
420 Some formats, including TIFF and JPEG allow you to change the units
421 spatial resolution information is stored in, if you set the tag that
422 changes this the Imager will convert C<i_xres> and C<i_yres> to those
423 units when it writes the file.
425 For example to set the resolution to 300 dpi:
427 $image->settag(name => 'i_xres', value => 300);
428 $image->settag(name => 'i_yres', value => 300);
430 If you want the file format to store the resolution in some other
431 unit, for example you can write a TIFF file that stores the resolution
432 in pixels per centimeter, you would do:
435 $image->settag(name => 'i_xres', value => 150 * 2.54);
436 $image->settag(name => 'i_yres', value => 150 * 2.54);
437 $image->settag(name => 'tiff_resolutionunit', value => 3);
443 Tony Cook <tony@develop-help.com>
447 L<Imager>, L<Imager::Files>, L<Imager::Draw>.