]> git.imager.perl.org - imager.git/blob - lib/Imager/Cookbook.pod
various typo fixes from David Steinbrunner and some other typo fixes
[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 Or:
20
21   my $image = Imager->new(file => $filename)
22     or die Imager->errstr;
23
24 See L<Imager::Files>.
25
26 =head2 Writing an image to a file
27
28   $image->write(file=>$filename) or die $image->errstr;
29
30 =head2 Write an animated GIF
31
32   # build an array of images to use in the gif
33   my  @images;
34   # synthesize the images or read them from files, it doesn't matter
35   ...
36
37   # write the gif
38   Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
39     or die Imager->errstr;
40
41 See L<Imager::Files/"Writing an animated GIF"> for a more detailed
42 example.
43
44 =head2 Reading multiple images from one file
45
46 Some formats, like GIF and TIFF support multiple images per file.  Use
47 the L<read_multi()|Imager::Files> method to read them:
48
49   my @images = Imager->read_multi(file=>$filename)
50     or die Imager->errstr;
51
52 =head2 Converting from one file format to another
53
54 This is as simple as reading the original file and writing the new
55 file, for single images:
56
57   my $image = Imager->new;
58   # Imager auto-detects the input file type
59   $image->read(file => $input_filename)
60     or die $image->errstr;
61   # Imager derives the output file format from the filename
62   $image->write(file => $output_filename)
63     or die $image->errstr;
64
65   # or you can supply a type parameter:
66   $image->write(file => $output_filename, type => 'gif')
67     or die $image->errstr;
68
69 The main issue that can occur with this is if the input file has
70 transparency and the output file format doesn't support that.  This
71 can be a problem when converting from GIF files to JPEG files for
72 example.
73
74 By default, if the output format doesn't support transparency, Imager
75 will compose the image onto a black background.  You can override that
76 by supplying an C<i_background> option to C<write()> or
77 C<write_multi()>:
78
79   $image->write(file => "foo.jpg", i_background => "#808080")
80     or die $image->errstr;
81
82 Some formats support multiple files, so if you want to convert from
83 say TIFF to JPEG, you'll need multiple output files:
84
85   my @images = Imager->read_multi(file => 'input.tif')
86     or die Imager->errstr;
87   my $index = 1;
88   for my $image (@images) {
89     $image->write(file => sprintf('output%02d.jpg', $index++))
90       or die $image->errstr;
91   }
92
93 =head2 Transparent PNG
94
95 To save to a transparent PNG (or GIF or TIFF) you need to start with
96 an image with transparency.
97
98 To make a transparent image, create an image object with 2 or 4
99 channels:
100
101   # RGB with alpha channel
102   my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
103
104   # Gray with alpha channel
105   my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
106
107 By default, the created image will be transparent.
108
109 Otherwise, if you have an existing image file with transparency,
110 simply read it, and the transparency will be preserved.
111
112 =head1 IMAGE SYNTHESIS
113
114 =head2 Creating an image
115
116 To create a simple RGB image, supply the image width and height to the
117 new() method:
118
119   my $rgb = Imager->new(xsize=>$width, ysize=>$height);
120
121 If you also want an alpha channel:
122
123   my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
124
125 To make a gray-scale image:
126
127   my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
128
129 and a gray-scale image with an alpha channel:
130
131   my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
132
133 When a new image is created this way all samples are set to zero -
134 black for 1 or 3 channel images, transparent black for 2 or 4 channel
135 images.
136
137 You can also create paletted images and images with more than 8-bits
138 per channel, see L<Imager::ImageTypes> for more details.
139
140 =head2 Setting the background of a new image
141
142 To set the background of a new image to a solid color, use the box()
143 method with no limits, and C<< filled=>1 >>:
144
145   $image->box(filled=>1, color=>$color);
146
147 As always, a color can be specified as an L<Imager::Color> object:
148
149   my $white = Imager::Color->new(255, 255, 255);
150   $image->box(filled=>1, color=>$white);
151
152 or you supply any single scalar that Imager::Color's new() method
153 accepts as a color description:
154
155   $image->box(filled=>1, color=>'white');
156   $image->box(filled=>1, color=>'#FF0000');
157   $image->box(filled=>1, color=>[ 255, 255, 255 ]);
158
159 You can also fill the image with a fill object:
160
161   use Imager::Fill;
162   # create the fill object
163   my $fill = Imager::Fill->new(hatch=>'check1x1')
164   $image->box(fill=>$fill);
165
166   # let Imager create one automatically
167   $image->box(fill=>{ hatch=>'check1x1' });
168
169 See L<Imager::Fill> for information on Imager's fill objects.
170
171 =head1 WORLD WIDE WEB
172
173 As with any CGI script it's up to you to validate data and set limits
174 on any parameters supplied to Imager.
175
176 For example, if you allow the caller to set the size of an output
177 image you should limit the size to prevent the client from specifying
178 an image size that will consume all available memory.
179
180 This is beside any other controls you need over access to data.
181
182 See L<CGI> for a module useful for processing CGI submitted data.
183
184 =head2 Returning an image from a CGI script
185
186 This is similar to writing to a file, but you also need to supply the
187 information needed by the web browser to identify the file format:
188
189   my $img = ....; # create the image and generate the contents
190   ++$|; # make sure the content type isn't buffered
191   print "Content-Type: image/png\n\n";
192   binmode STDOUT;
193   $img->write(fd=>fileno(STDOUT), type=>'png')
194     or die $img->errstr;
195
196 You need to set the Content-Type header depending on the file format
197 you send to the web browser.
198
199 If you want to supply a content-length header, write the image to a
200 scalar as a buffer:
201
202   my $img = ....; # create the image and generate the contents
203   my $data;
204   $img->write(type=>'png', data=>\$data)
205     or die $img->errstr;
206   print "Content-Type: image/png\n";
207   print "Content-Length: ",length($data),"\n\n";
208   binmode STDOUT;
209   print $data;
210
211 See C<samples/samp-scale.cgi> and C<samples/samp-image.cgi> for a
212 couple of simple examples of producing an image from CGI.
213
214 =head2 Inserting a CGI image in a page
215
216 There's occasionally confusion on how to display an image generated by
217 Imager in a page generated by a CGI.
218
219 Your web browser handles this process as two requests, one for the
220 HTML page, and another for the image itself.
221
222 Each request needs to perform validation since an attacker can control
223 the values supplied to both requests.
224
225 How you make the data available to the image generation code depends
226 on your application.
227
228 See C<samples/samp-form.cgi> and C<samples/samp-image.cgi> in the
229 Imager distribution for one approach.  The POD in C<samp-form.cgi>
230 also discusses some of the issues involved.
231
232 =head2 Parsing an image posted via CGI
233
234 C<WARNING>: file format attacks have become a common attack vector,
235 make sure you have up to date image file format libraries, otherwise
236 trying to parse uploaded files, whether with Imager or some other
237 tool, may result in a remote attacker being able to run their own code
238 on your system.
239
240 If your HTML form uses the correct magic, it can upload files to your
241 CGI script, in particular, you need to use C< method="post" > and
242 C<enctype="multipart/form-data"> in the C<form> tag, and use
243 C<type="file"> in the C<input>, for example:
244
245   <form action="/cgi-bin/yourprogram" method="post" 
246         enctype="multipart/form-data">
247     <input type="file" name="myimage" />
248     <input type="submit value="Upload Image" />
249   </form>
250
251 To process the form:
252
253 =over
254
255 =item 1.
256
257 first check that the user supplied a file
258
259 =item 2.
260
261 get the file handle
262
263 =item 3.
264
265 have Imager read the image
266
267 =back
268
269   # returns the client's name for the file, don't open this locally
270   my $cgi = CGI->new;
271   # 1. check the user supplied a file
272   my $filename = $cgi->param('myimage');
273   if ($filename) {
274     # 2. get the file handle
275     my $fh = $cgi->upload('myimage');
276     if ($fh) {
277       binmode $fh;
278       
279       # 3. have Imager read the image
280       my $img = Imager->new;
281       if ($img->read(fh=>$fh)) {
282         # we can now process the image
283       }
284     }
285     # else, you probably have an incorrect form or input tag
286   }
287   # else, the user didn't select a file
288
289 See C<samples/samp-scale.cgi> and C<samples/samp-tags.cgi> in the
290 Imager distribution for example code.
291
292 You may also want to set limits on the size of the image read, using
293 Imager's C<set_file_limits> method, documented in
294 L<Imager::Files/set_file_limits()>.  For example:
295
296   # limit to 10 million bytes of memory usage
297   Imager->set_file_limits(bytes => 10_000_000);
298
299   # limit to 1024 x 1024
300   Imager->set_file_limits(width => 1024, height => 1024);
301
302 =head1 DRAWING
303
304 =head2 Adding a border to an image
305
306 First make a new image with space for the border:
307
308   my $border_width = ...;
309   my $border_height = ...;
310   my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
311                         ysize => $source->getheight() + 2 * $border_height,
312                         bits => $source->bits,
313                         channels => $source->getchannels);
314
315 Then paste the source image into the new image:
316
317   $out->paste(left => $border_width,
318               top => $border_height,
319               img => $source);
320
321 Whether you draw the border before or after pasting the original image
322 depends on whether you want the border to overlap the image, for
323 example a semi-transparent border drawn after pasting the source image
324 could overlap the edge without hiding it.
325
326 If you want a solid border you could just fill the image before
327 pasting the source for simplicity:
328
329   $out->box(filled=>1, color=>'red');
330   $out->paste(left => $border_width,
331               top => $border_height,
332               img => $source);
333
334
335 =head1 TEXT
336
337 =head2 Drawing text
338
339 =head2 Aligning text
340
341 =head2 Measuring text
342
343 =head2 Word wrapping text
344
345 =head2 Shearing (slanting) or Rotating text
346
347 This requires that you have Imager installed with FreeType 2.x support
348 installed, and that the font be created using the FreeType 2.x driver,
349 for example:
350
351   my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
352
353 First you need a transformation matrix, for shearing that could be:
354
355   my $angle_in_radians = ...;
356   my $tan_angle = sin($angle_rads) / cos($angle_rads);
357   # shear horizontally, supply this as y instead to do it vertically
358   my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
359
360 For rotation that would be:
361
362   my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
363
364 or:
365
366   my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
367
368 Feed that to the font object:
369
370   $font->transform(matrix => $matrix);
371
372 and draw the text as normal:
373
374   $image->string(string => $text,
375                  x => $where_x,
376                  y => $where_y,
377                  color => $color,
378                  font => $font);
379
380 See samples/slant_text.pl for a comprehensive example, including
381 calculating the transformed bounding box to create an image to fit the
382 transformed text into.
383
384 =head1 IMAGE TRANSFORMATION
385
386 =head2 Shearing an image
387
388 =head2 Convert to gray-scale
389
390 To convert an RGB image to a gray-scale image, use the convert method:
391
392   my $grey = $image->convert(preset => 'gray');
393
394 convert() returns a new image.
395
396 See: L<Imager::Transformations/"Color transformations">
397
398 =head1 METADATA
399
400 =head2 Image format
401
402 When Imager reads a file it does a magic number check to determine the
403 file type, so C<foo.png> could actually be a GIF image, and Imager
404 will read it anyway.
405
406 You can check the actual format of the image by looking at the
407 C<i_format> tag.
408
409   my $format = $image->tags(name=>'i_format');
410
411 =head2 Image spatial resolution
412
413 Most image file formats store information about the physical size of
414 the pixels, though in some cases that information isn't useful.
415
416 Imager stores this information in the tags C<i_xres> and C<i_yres>,
417 and this is always stored in dots per inch.
418
419 Some formats, including TIFF and JPEG allow you to change the units
420 spatial resolution information is stored in, if you set the tag that
421 changes this the Imager will convert C<i_xres> and C<i_yres> to those
422 units when it writes the file.
423
424 For example to set the resolution to 300 dpi:
425
426   $image->settag(name => 'i_xres', value => 300);
427   $image->settag(name => 'i_yres', value => 300);
428
429 If you want the file format to store the resolution in some other
430 unit, for example you can write a TIFF file that stores the resolution
431 in pixels per centimeter, you would do:
432
433   # 150 pixels/cm
434   $image->settag(name => 'i_xres', value => 150 * 2.54);
435   $image->settag(name => 'i_yres', value => 150 * 2.54);
436   $image->settag(name => 'tiff_resolutionunit', value => 3);
437
438 Keywords: DPI
439
440 =head1 IMAGE MANIPULATION
441
442 =head2 Replacing a color with transparency
443 X<replacing colors>
444
445 To replace a color with transparency you can use the
446 L<Imager::Filters/difference()> method.
447
448   # make a work image the same size as our input
449   my $work = Imager->new(xsize => $in->getwidth, ysize => $in->getheight,
450                          channels => $in->getchannels);
451   # and fill it with the color we want transparent
452   $work->box(filled => 1, color => $color);
453
454   # get an image with that color replaced with transparent black
455   my $out = $work->difference(other => $in);
456
457 =head1 SPECIAL EFFECTS
458
459 =head2 Drop Shadows
460 X<drop shadow>X<effects, drop shadow>
461
462 This can be used for a glow effect as well.
463
464 First create a new image, either with an alpha channel (if you want
465 transparency behind the shadow) or without, if you want a background
466 color:
467
468   my $out = Imager->new
469      (
470      xsize => $shadow_size * 2 + $src->getwidth,
471      ysize => $shadow_size * 2 + $src->getheight,
472      channels => 4,
473      );
474   # fill it with your background color, if you want one
475   # $out->box(filled => 1, color => $back_color);
476
477 Make a work image to render the shadow on:
478
479   my $shadow_work = Imager->new
480     (
481     xsize => $back->getwidth,
482     ysize => $back->getheight,
483     channels => 1,
484     );
485
486 Extract the alpha channel from the source image, first the alpha version:
487
488   my $alpha = $src->convert(preset => "alpha");
489
490 and draw that on the work shadow:
491
492   $shadow_work->paste
493     (
494     src => $slpha,
495     left => $shadow_size,
496     top => $shadow_size,
497     );
498
499 otherwise just draw a box for the non-alpha source:
500
501   $shadow_work->box
502     (
503     filled => 1,
504     color => [ 255 ],
505     xmin => $shadow_size,
506     ymin => $shadow_size,
507     xmax => $shadow_size + $src->getwidth() - 1,
508     ymax => $shadow_size + $src->getheight() - 1,
509     );
510
511 Blur the work shadow:
512
513   $shadow_work->filter(type => "gaussian", stddev => $shadow_size);
514
515 Convert it to an RGB image with alpha:
516
517   $shadow_work = $shadow_work->convert
518      (
519       matrix => [ [ 0, $red / 255 ],
520                    [ 0, $green / 255 ],
521                    [ 0, $blue / 255 ],
522                    [ 1 ] ]
523      );
524
525 Draw that on the output image:
526
527   $out->rubthrough(src => $shadow_work);
528
529 Draw our original image on the output image, perhaps with an offset:
530
531   $out->rubthrough
532     (
533     src => $src,
534     tx => $shadow_size + $x_offset,
535     ty => $shadow_size + $y_offset,
536     );
537
538 See F<samples/drop_shadow.pl> for an example of this recipe.
539
540 =head1 AUTHOR
541
542 Tony Cook <tony@develop-help.com>
543
544 =head1 SEE ALSO
545
546 L<Imager>, L<Imager::Files>, L<Imager::Draw>.
547
548 =cut