]> git.imager.perl.org - imager.git/blob - lib/Imager/Cookbook.pod
improve coverage testing Imager::Color::Float and fix a bug
[imager.git] / lib / Imager / Cookbook.pod
1 =head1 NAME
2
3 Imager::Cookbook - recipes working with Imager
4
5 =head1 DESCRIPTION
6
7 Various simple and not so simple ways to do things with Imager.
8
9 =head1 FILES
10
11 This is described in detail in L<Imager::Files>.
12
13 =head2 Reading an image from a file
14
15   my $image = Imager->new;
16
17   $image->read(file=>$filename) or die $image->errstr;
18
19 See L<Imager::Files>.
20
21 =head2 Writing an image to a file
22
23   $image->write(file=>$filename) or die $image->errstr;
24
25 =head2 Write an animated GIF
26
27   # build an array of images to use in the gif
28   my  @images;
29   # synthesize the images or read them from files, it doesn't matter
30   ...
31
32   # write the gif
33   Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
34     or die Imager->errstr;
35
36 See L<Imager::Files/"Writing an animated GIF"> for a more detailed
37 example.
38
39 =head2 Reading multiple images from one file
40
41 Some formats, like GIF and TIFF support multiple images per file.  Use
42 the L<read_multi()|Imager::Files> method to read them:
43
44   my @images = Imager->read_multi(file=>$filename)
45     or die Imager->errstr;
46
47 =head2 Converting from one file format to another
48
49 This is as simple as reading the original file and writing the new
50 file, for single images:
51
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;
59
60   # or you can supply a type parameter:
61   $image->write(file => $output_filename, type => 'gif')
62     or die $image->errstr;
63
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
67 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
84 say 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
94 =head2 Transparent PNG
95
96 To save to a transparent PNG (or GIF or TIFF) you need to start with
97 an image with transparency.
98
99 To make a transparent image, create an image object with 2 or 4
100 channels:
101
102   # RGB with alpha channel
103   my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
104
105   # Gray with alpha channel
106   my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
107
108 By default, the created image will be transparent.
109
110 Otherwise, if you have an existing image file with transparency,
111 simply read it, and the transparency will be preserved.
112
113 =head1 IMAGE SYNTHESIS
114
115 =head2 Creating an image
116
117 To create a simple RGB image, supply the image width and height to the
118 new() method:
119
120   my $rgb = Imager->new(xsize=>$width, ysize=>$height);
121
122 If you also want an alpha channel:
123
124   my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
125
126 To make a gray-scale image:
127
128   my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
129
130 and a gray-scale image with an alpha channel:
131
132   my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
133
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
136 images.
137
138 You can also create paletted images and images with more than 8-bits
139 per channel, see L<Imager::ImageTypes> for more details.
140
141 =head2 Setting the background of a new image
142
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 >>:
145
146   $image->box(filled=>1, color=>$color);
147
148 As always, a color can be specified as an L<Imager::Color> object:
149
150   my $white = Imager::Color->new(255, 255, 255);
151   $image->box(filled=>1, color=>$white);
152
153 or you supply any single scalar that Imager::Color's new() method
154 accepts as a color description:
155
156   $image->box(filled=>1, color=>'white');
157   $image->box(filled=>1, color=>'#FF0000');
158   $image->box(filled=>1, color=>[ 255, 255, 255 ]);
159
160 You can also fill the image with a fill object:
161
162   use Imager::Fill;
163   # create the fill object
164   my $fill = Imager::Fill->new(hatch=>'check1x1')
165   $image->box(fill=>$fill);
166
167   # let Imager create one automatically
168   $image->box(fill=>{ hatch=>'check1x1' });
169
170 See L<Imager::Fill> for information on Imager's fill objects.
171
172 =head1 WORLD WIDE WEB
173
174 As with any CGI script it's up to you to validate data and set limits
175 on any parameters supplied to Imager.
176
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.
180
181 This is beside any any other controls you need over access to data.
182
183 See L<CGI> for a module useful for processing CGI submitted data.
184
185 =head2 Returning an image from a CGI script
186
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:
189
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";
193   binmode STDOUT;
194   $img->write(fd=>fileno(STDOUT), type=>'png')
195     or die $img->errstr;
196
197 You need to set the Content-Type header depending on the file format
198 you send to the web browser.
199
200 If you want to supply a content-length header, write the image to a
201 scalar as a buffer:
202
203   my $img = ....; # create the image and generate the contents
204   my $data;
205   $img->write(type=>'png', data=>\$data)
206     or die $img->errstr;
207   print "Content-Type: image/png\n";
208   print "Content-Length: ",length($data),"\n\n";
209   binmode STDOUT;
210   print $data;
211
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.
214
215 =head2 Inserting a CGI image in a page
216
217 There's occasionally confusion on how to display an image generated by
218 Imager in a page generated by a CGI.
219
220 Your web browser handles this process as two requests, one for the
221 HTML page, and another for the image itself.
222
223 Each request needs to perform validation since an attacker can control
224 the values supplied to both requests.
225
226 How you make the data available to the image generation code depends
227 on your application.
228
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.
232
233 =head2 Parsing an image posted via CGI
234
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
239 on your system.
240
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:
245
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" />
250   </form>
251
252 To process the form:
253
254 =over
255
256 =item 1.
257
258 first check that the user supplied a file
259
260 =item 2.
261
262 get the file handle
263
264 =item 3.
265
266 have Imager read the image
267
268 =back
269
270   # returns the client's name for the file, don't open this locally
271   my $cgi = CGI->new;
272   # 1. check the user supplied a file
273   my $filename = $cgi->param('myimage');
274   if ($filename) {
275     # 2. get the file handle
276     my $fh = $cgi->upload('myimage');
277     if ($fh) {
278       binmode $fh;
279       
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
284       }
285     }
286     # else, you probably have an incorrect form or input tag
287   }
288   # else, the user didn't select a file
289
290 See C<samples/samp-scale.cgi> and C<samples/samp-tags.cgi> in the
291 Imager distribution for example code.
292
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:
296
297   # limit to 10 million bytes of memory usage
298   Imager->set_file_limits(bytes => 10_000_000);
299
300   # limit to 1024 x 1024
301   Imager->set_file_limits(width => 1024, height => 1024);
302
303 =head1 DRAWING
304
305 =head2 Adding a border to an image
306
307 First make a new image with space for the border:
308
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);
315
316 Then paste the source image into the new image:
317
318   $out->paste(left => $border_width,
319               top => $border_height,
320               img => $source);
321
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.
326
327 If you want a solid border you could just fill the image before
328 pasting the source for simplicity:
329
330   $out->box(filled=>1, color=>'red');
331   $out->paste(left => $border_width,
332               top => $border_height,
333               img => $source);
334
335
336 =head1 TEXT
337
338 =head2 Drawing text
339
340 =head2 Aligning text
341
342 =head2 Measuring text
343
344 =head2 Word wrapping text
345
346 =head2 Shearing (slanting) or Rotating text
347
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,
350 for example:
351
352   my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
353
354 First you need a transformation matrix, for shearing that could be:
355
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);
360
361 For rotation that would be:
362
363   my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
364
365 or:
366
367   my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
368
369 Feed that to the font object:
370
371   $font->transform(matrix => $matrix);
372
373 and draw the text as normal:
374
375   $image->string(string => $text,
376                  x => $where_x,
377                  y => $where_y,
378                  color => $color,
379                  font => $font);
380
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.
384
385 =head1 IMAGE TRANSFORMATION
386
387 =head2 Shearing an image
388
389 =head2 Convert to gray-scale
390
391 To convert an RGB image to a gray-scale image, use the convert method:
392
393   my $grey = $image->convert(preset => 'gray');
394
395 convert() returns a new image.
396
397 See: L<Imager::Transformations/"Color transformations">
398
399 =head1 METADATA
400
401 =head2 Image format
402
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
405 will read it anyway.
406
407 You can check the actual format of the image by looking at the
408 C<i_format> tag.
409
410   my $format = $image->tags(name=>'i_format');
411
412 =head2 Image spatial resolution
413
414 Most image file formats store information about the physical size of
415 the pixels, though in some cases that information isn't useful.
416
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.
419
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.
424
425 For example to set the resolution to 300 dpi:
426
427   $image->settag(name => 'i_xres', value => 300);
428   $image->settag(name => 'i_yres', value => 300);
429
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:
433
434   # 150 pixels/cm
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);
438
439 Keywords: DPI
440
441 =head1 AUTHOR
442
443 Tony Cook <tony@develop-help.com>
444
445 =head1 SEE ALSO
446
447 L<Imager>, L<Imager::Files>, L<Imager::Draw>.
448
449 =cut