]> git.imager.perl.org - imager.git/blob - lib/Imager/Cookbook.pod
don't supply a default for a missing channel list
[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 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
72 C<write_multi()>:
73
74   $image->write(file => "foo.jpg", i_background => "#808080")
75     or die $image->errstr;
76
77 Some formats support multiple files, so if you want to convert from
78 say TIFF to JPEG, you'll need multiple output files:
79
80   my @images = Imager->read_multi(file => 'input.tif')
81     or die Imager->errstr;
82   my $index = 1;
83   for my $image (@images) {
84     $image->write(file => sprintf('output%02d.jpg', $index++))
85       or die $image->errstr;
86   }
87
88 =head2 Transparent PNG
89
90 To save to a transparent PNG (or GIF or TIFF) you need to start with
91 an image with transparency.
92
93 To make a transparent image, create an image object with 2 or 4
94 channels:
95
96   # RGB with alpha channel
97   my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
98
99   # Gray with alpha channel
100   my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
101
102 By default, the created image will be transparent.
103
104 Otherwise, if you have an existing image file with transparency,
105 simply read it, and the transparency will be preserved.
106
107 =head1 IMAGE SYNTHESIS
108
109 =head2 Creating an image
110
111 To create a simple RGB image, supply the image width and height to the
112 new() method:
113
114   my $rgb = Imager->new(xsize=>$width, ysize=>$height);
115
116 If you also want an alpha channel:
117
118   my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
119
120 To make a gray-scale image:
121
122   my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
123
124 and a gray-scale image with an alpha channel:
125
126   my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
127
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
130 images.
131
132 You can also create paletted images and images with more than 8-bits
133 per channel, see L<Imager::ImageTypes> for more details.
134
135 =head2 Setting the background of a new image
136
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 >>:
139
140   $image->box(filled=>1, color=>$color);
141
142 As always, a color can be specified as an L<Imager::Color> object:
143
144   my $white = Imager::Color->new(255, 255, 255);
145   $image->box(filled=>1, color=>$white);
146
147 or you supply any single scalar that Imager::Color's new() method
148 accepts as a color description:
149
150   $image->box(filled=>1, color=>'white');
151   $image->box(filled=>1, color=>'#FF0000');
152   $image->box(filled=>1, color=>[ 255, 255, 255 ]);
153
154 You can also fill the image with a fill object:
155
156   use Imager::Fill;
157   # create the fill object
158   my $fill = Imager::Fill->new(hatch=>'check1x1')
159   $image->box(fill=>$fill);
160
161   # let Imager create one automatically
162   $image->box(fill=>{ hatch=>'check1x1' });
163
164 See L<Imager::Fill> for information on Imager's fill objects.
165
166 =head1 WORLD WIDE WEB
167
168 As with any CGI script it's up to you to validate data and set limits
169 on any parameters supplied to Imager.
170
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.
174
175 This is beside any any other controls you need over access to data.
176
177 See L<CGI> for a module useful for processing CGI submitted data.
178
179 =head2 Returning an image from a CGI script
180
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:
183
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";
187   binmode STDOUT;
188   $img->write(fd=>fileno(STDOUT), type=>'png')
189     or die $img->errstr;
190
191 You need to set the Content-Type header depending on the file format
192 you send to the web browser.
193
194 If you want to supply a content-length header, write the image to a
195 scalar as a buffer:
196
197   my $img = ....; # create the image and generate the contents
198   my $data;
199   $img->write(type=>'png', data=>\$data)
200     or die $img->errstr;
201   print "Content-Type: image/png\n";
202   print "Content-Length: ",length($data),"\n\n";
203   binmode STDOUT;
204   print $data;
205
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.
208
209 =head2 Inserting a CGI image in a page
210
211 There's occasionally confusion on how to display an image generated by
212 Imager in a page generated by a CGI.
213
214 Your web browser handles this process as two requests, one for the
215 HTML page, and another for the image itself.
216
217 Each request needs to perform validation since an attacker can control
218 the values supplied to both requests.
219
220 How you make the data available to the image generation code depends
221 on your application.
222
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.
226
227 =head2 Parsing an image posted via CGI
228
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
233 on your system.
234
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:
239
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" />
244   </form>
245
246 To process the form:
247
248 =over
249
250 =item 1.
251
252 first check that the user supplied a file
253
254 =item 2.
255
256 get the file handle
257
258 =item 3.
259
260 have Imager read the image
261
262 =back
263
264   # returns the client's name for the file, don't open this locally
265   my $cgi = CGI->new;
266   # 1. check the user supplied a file
267   my $filename = $cgi->param('myimage');
268   if ($filename) {
269     # 2. get the file handle
270     my $fh = $cgi->upload('myimage');
271     if ($fh) {
272       binmode $fh;
273       
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
278       }
279     }
280     # else, you probably have an incorrect form or input tag
281   }
282   # else, the user didn't select a file
283
284 See C<samples/samp-scale.cgi> and C<samples/samp-tags.cgi> in the
285 Imager distribution for example code.
286
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:
290
291   # limit to 10 million bytes of memory usage
292   Imager->set_file_limits(bytes => 10_000_000);
293
294   # limit to 1024 x 1024
295   Imager->set_file_limits(width => 1024, height => 1024);
296
297 =head1 DRAWING
298
299 =head2 Adding a border to an image
300
301 First make a new image with space for the border:
302
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);
309
310 Then paste the source image into the new image:
311
312   $out->paste(left => $border_width,
313               top => $border_height,
314               img => $source);
315
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.
320
321 If you want a solid border you could just fill the image before
322 pasting the source for simplicity:
323
324   $out->box(filled=>1, color=>'red');
325   $out->paste(left => $border_width,
326               top => $border_height,
327               img => $source);
328
329
330 =head1 TEXT
331
332 =head2 Drawing text
333
334 =head2 Aligning text
335
336 =head2 Measuring text
337
338 =head2 Word wrapping text
339
340 =head2 Shearing (slanting) or Rotating text
341
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,
344 for example:
345
346   my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
347
348 First you need a transformation matrix, for shearing that could be:
349
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);
354
355 For rotation that would be:
356
357   my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
358
359 or:
360
361   my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
362
363 Feed that to the font object:
364
365   $font->transform(matrix => $matrix);
366
367 and draw the text as normal:
368
369   $image->string(string => $text,
370                  x => $where_x,
371                  y => $where_y,
372                  color => $color,
373                  font => $font);
374
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.
378
379 =head1 IMAGE TRANSFORMATION
380
381 =head2 Shearing an image
382
383 =head2 Convert to gray-scale
384
385 To convert an RGB image to a gray-scale image, use the convert method:
386
387   my $grey = $image->convert(preset => 'gray');
388
389 convert() returns a new image.
390
391 See: L<Imager::Transformations/"Color transformations">
392
393 =head1 METADATA
394
395 =head2 Image format
396
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
399 will read it anyway.
400
401 You can check the actual format of the image by looking at the
402 C<i_format> tag.
403
404   my $format = $image->tags(name=>'i_format');
405
406 =head2 Image spatial resolution
407
408 Most image file formats store information about the physical size of
409 the pixels, though in some cases that information isn't useful.
410
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.
413
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.
418
419 For example to set the resolution to 300 dpi:
420
421   $image->settag(name => 'i_xres', value => 300);
422   $image->settag(name => 'i_yres', value => 300);
423
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:
427
428   # 150 pixels/cm
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);
432
433 Keywords: DPI
434
435 =head1 AUTHOR
436
437 Tony Cook <tony@develop-help.com>
438
439 =head1 SEE ALSO
440
441 L<Imager>, L<Imager::Files>, L<Imager::Draw>.
442
443 =cut