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 By default, if the output format doesn't support transparency, Imager
70 will compose the image onto a black background. You can override that
71 by supplying an C<i_background> option to C<write()> or
74 $image->write(file => "foo.jpg", i_background => "#808080")
75 or die $image->errstr;
77 Some formats support multiple files, so if you want to convert from
78 say TIFF to JPEG, you'll need multiple output files:
80 my @images = Imager->read_multi(file => 'input.tif')
81 or die Imager->errstr;
83 for my $image (@images) {
84 $image->write(file => sprintf('output%02d.jpg', $index++))
85 or die $image->errstr;
88 =head2 Transparent PNG
90 To save to a transparent PNG (or GIF or TIFF) you need to start with
91 an image with transparency.
93 To make a transparent image, create an image object with 2 or 4
96 # RGB with alpha channel
97 my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
99 # Gray with alpha channel
100 my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
102 By default, the created image will be transparent.
104 Otherwise, if you have an existing image file with transparency,
105 simply read it, and the transparency will be preserved.
107 =head1 IMAGE SYNTHESIS
109 =head2 Creating an image
111 To create a simple RGB image, supply the image width and height to the
114 my $rgb = Imager->new(xsize=>$width, ysize=>$height);
116 If you also want an alpha channel:
118 my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
120 To make a gray-scale image:
122 my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
124 and a gray-scale image with an alpha channel:
126 my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
128 When a new image is created this way all samples are set to zero -
129 black for 1 or 3 channel images, transparent black for 2 or 4 channel
132 You can also create paletted images and images with more than 8-bits
133 per channel, see L<Imager::ImageTypes> for more details.
135 =head2 Setting the background of a new image
137 To set the background of a new image to a solid color, use the box()
138 method with no limits, and C<< filled=>1 >>:
140 $image->box(filled=>1, color=>$color);
142 As always, a color can be specified as an L<Imager::Color> object:
144 my $white = Imager::Color->new(255, 255, 255);
145 $image->box(filled=>1, color=>$white);
147 or you supply any single scalar that Imager::Color's new() method
148 accepts as a color description:
150 $image->box(filled=>1, color=>'white');
151 $image->box(filled=>1, color=>'#FF0000');
152 $image->box(filled=>1, color=>[ 255, 255, 255 ]);
154 You can also fill the image with a fill object:
157 # create the fill object
158 my $fill = Imager::Fill->new(hatch=>'check1x1')
159 $image->box(fill=>$fill);
161 # let Imager create one automatically
162 $image->box(fill=>{ hatch=>'check1x1' });
164 See L<Imager::Fill> for information on Imager's fill objects.
166 =head1 WORLD WIDE WEB
168 As with any CGI script it's up to you to validate data and set limits
169 on any parameters supplied to Imager.
171 For example, if you allow the caller to set the size of an output
172 image you should limit the size to prevent the client from specifying
173 an image size that will consume all available memory.
175 This is beside any any other controls you need over access to data.
177 See L<CGI> for a module useful for processing CGI submitted data.
179 =head2 Returning an image from a CGI script
181 This is similar to writing to a file, but you also need to supply the
182 information needed by the web browser to identify the file format:
184 my $img = ....; # create the image and generate the contents
185 ++$|; # make sure the content type isn't buffered
186 print "Content-Type: image/png\n\n";
188 $img->write(fd=>fileno(STDOUT), type=>'png')
191 You need to set the Content-Type header depending on the file format
192 you send to the web browser.
194 If you want to supply a content-length header, write the image to a
197 my $img = ....; # create the image and generate the contents
199 $img->write(type=>'png', data=>\$data)
201 print "Content-Type: image/png\n";
202 print "Content-Length: ",length($data),"\n\n";
206 See C<samples/samp-scale.cgi> and C<samples/samp-image.cgi> for a
207 couple of simple examples of producing an image from CGI.
209 =head2 Inserting a CGI image in a page
211 There's occasionally confusion on how to display an image generated by
212 Imager in a page generated by a CGI.
214 Your web browser handles this process as two requests, one for the
215 HTML page, and another for the image itself.
217 Each request needs to perform validation since an attacker can control
218 the values supplied to both requests.
220 How you make the data available to the image generation code depends
223 See C<samples/samp-form.cgi> and C<samples/samp-image.cgi> in the
224 Imager distribution for one approach. The POD in C<samp-form.cgi>
225 also discusses some of the issues involved.
227 =head2 Parsing an image posted via CGI
229 C<WARNING>: file format attacks have become a common attack vector,
230 make sure you have up to date image file format libraries, otherwise
231 trying to parse uploaded files, whether with Imager or some other
232 tool, may result in a remote attacker being able to run their own code
235 If your HTML form uses the correct magic, it can upload files to your
236 CGI script, in particular, you need to use C< method="post" > and
237 C<enctype="multipart/form-data"> in the C<form> tag, and use
238 C<type="file"> in the C<input>, for example:
240 <form action="/cgi-bin/yourprogram" method="post"
241 enctype="multipart/form-data">
242 <input type="file" name="myimage" />
243 <input type="submit value="Upload Image" />
252 first check that the user supplied a file
260 have Imager read the image
264 # returns the client's name for the file, don't open this locally
266 # 1. check the user supplied a file
267 my $filename = $cgi->param('myimage');
269 # 2. get the file handle
270 my $fh = $cgi->upload('myimage');
274 # 3. have Imager read the image
275 my $img = Imager->new;
276 if ($img->read(fh=>$fh)) {
277 # we can now process the image
280 # else, you probably have an incorrect form or input tag
282 # else, the user didn't select a file
284 See C<samples/samp-scale.cgi> and C<samples/samp-tags.cgi> in the
285 Imager distribution for example code.
287 You may also want to set limits on the size of the image read, using
288 Imager's C<set_file_limits> method, documented in
289 L<Imager::Files/set_file_limits()>. For example:
291 # limit to 10 million bytes of memory usage
292 Imager->set_file_limits(bytes => 10_000_000);
294 # limit to 1024 x 1024
295 Imager->set_file_limits(width => 1024, height => 1024);
299 =head2 Adding a border to an image
301 First make a new image with space for the border:
303 my $border_width = ...;
304 my $border_height = ...;
305 my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
306 ysize => $source->getheight() + 2 * $border_height,
307 bits => $source->bits,
308 channels => $source->getchannels);
310 Then paste the source image into the new image:
312 $out->paste(left => $border_width,
313 top => $border_height,
316 Whether you draw the border before or after pasting the original image
317 depends on whether you want the border to overlap the image, for
318 example a semi-transparent border drawn after pasting the source image
319 could overlap the edge without hiding it.
321 If you want a solid border you could just fill the image before
322 pasting the source for simplicity:
324 $out->box(filled=>1, color=>'red');
325 $out->paste(left => $border_width,
326 top => $border_height,
336 =head2 Measuring text
338 =head2 Word wrapping text
340 =head2 Shearing (slanting) or Rotating text
342 This requires that you have Imager installed with FreeType 2.x support
343 installed, and that the font be created using the FreeType 2.x driver,
346 my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
348 First you need a transformation matrix, for shearing that could be:
350 my $angle_in_radians = ...;
351 my $tan_angle = sin($angle_rads) / cos($angle_rads);
352 # shear horizontally, supply this as y instead to do it vertically
353 my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
355 For rotation that would be:
357 my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
361 my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
363 Feed that to the font object:
365 $font->transform(matrix => $matrix);
367 and draw the text as normal:
369 $image->string(string => $text,
375 See samples/slant_text.pl for a comprehensive example, including
376 calculating the transformed bounding box to create an image to fit the
377 transformed text into.
379 =head1 IMAGE TRANSFORMATION
381 =head2 Shearing an image
383 =head2 Convert to gray-scale
385 To convert an RGB image to a gray-scale image, use the convert method:
387 my $grey = $image->convert(preset => 'gray');
389 convert() returns a new image.
391 See: L<Imager::Transformations/"Color transformations">
397 When Imager reads a file it does a magic number check to determine the
398 file type, so C<foo.png> could actually be a GIF image, and Imager
401 You can check the actual format of the image by looking at the
404 my $format = $image->tags(name=>'i_format');
406 =head2 Image spatial resolution
408 Most image file formats store information about the physical size of
409 the pixels, though in some cases that information isn't useful.
411 Imager stores this information in the tags C<i_xres> and C<i_yres>,
412 and this is always stored in dots per inch.
414 Some formats, including TIFF and JPEG allow you to change the units
415 spatial resolution information is stored in, if you set the tag that
416 changes this the Imager will convert C<i_xres> and C<i_yres> to those
417 units when it writes the file.
419 For example to set the resolution to 300 dpi:
421 $image->settag(name => 'i_xres', value => 300);
422 $image->settag(name => 'i_yres', value => 300);
424 If you want the file format to store the resolution in some other
425 unit, for example you can write a TIFF file that stores the resolution
426 in pixels per centimeter, you would do:
429 $image->settag(name => 'i_xres', value => 150 * 2.54);
430 $image->settag(name => 'i_yres', value => 150 * 2.54);
431 $image->settag(name => 'tiff_resolutionunit', value => 3);
437 Tony Cook <tony@develop-help.com>
441 L<Imager>, L<Imager::Files>, L<Imager::Draw>.