1Imager::Cookbook(3)   User Contributed Perl Documentation  Imager::Cookbook(3)
2
3
4

NAME

6       Imager::Cookbook - recipes working with Imager
7

DESCRIPTION

9       Various simple and not so simple ways to do things with Imager.
10

FILES

12       This is described in detail in Imager::Files.
13
14   Reading an image from a file
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 Imager::Files.
25
26   Writing an image to a file
27         $image->write(file=>$filename) or die $image->errstr;
28
29   Write an animated GIF
30         # build an array of images to use in the gif
31         my  @images;
32         # synthesize the images or read them from files, it doesn't matter
33         ...
34
35         # write the gif
36         Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
37           or die Imager->errstr;
38
39       See "Writing an animated GIF" in Imager::Files for a more detailed
40       example.
41
42   Reading multiple images from one file
43       Some formats, like GIF and TIFF support multiple images per file.  Use
44       the read_multi() method to read them:
45
46         my @images = Imager->read_multi(file=>$filename)
47           or die Imager->errstr;
48
49   Converting from one file format to another
50       This is as simple as reading the original file and writing the new
51       file, for single images:
52
53         my $image = Imager->new;
54         # Imager auto-detects the input file type
55         $image->read(file => $input_filename)
56           or die $image->errstr;
57         # Imager derives the output file format from the filename
58         $image->write(file => $output_filename)
59           or die $image->errstr;
60
61         # or you can supply a type parameter:
62         $image->write(file => $output_filename, type => 'gif')
63           or die $image->errstr;
64
65       The main issue that can occur with this is if the input file has
66       transparency and the output file format doesn't support that.  This can
67       be a problem when converting from GIF files to JPEG files for 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 "i_background" option to "write()" or "write_multi()":
72
73         $image->write(file => "foo.jpg", i_background => "#808080")
74           or die $image->errstr;
75
76       Some formats support multiple files, so if you want to convert from say
77       TIFF to JPEG, you'll need multiple output files:
78
79         my @images = Imager->read_multi(file => 'input.tif')
80           or die Imager->errstr;
81         my $index = 1;
82         for my $image (@images) {
83           $image->write(file => sprintf('output%02d.jpg', $index++))
84             or die $image->errstr;
85         }
86
87   Transparent PNG
88       To save to a transparent PNG (or GIF or TIFF) you need to start with an
89       image with transparency.
90
91       To make a transparent image, create an image object with 2 or 4
92       channels:
93
94         # RGB with alpha channel
95         my $rgba = Imager->new(xsize => $width, ysize => $height, channels => 4);
96
97         # Gray with alpha channel
98         my $graya = Imager->new(xsize => $width, ysize => $height, channels => 2);
99
100       By default, the created image will be transparent.
101
102       Otherwise, if you have an existing image file with transparency, simply
103       read it, and the transparency will be preserved.
104

IMAGE SYNTHESIS

106   Creating an image
107       To create a simple RGB image, supply the image width and height to the
108       new() method:
109
110         my $rgb = Imager->new(xsize=>$width, ysize=>$height);
111
112       If you also want an alpha channel:
113
114         my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
115
116       To make a gray-scale image:
117
118         my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
119
120       and a gray-scale image with an alpha channel:
121
122         my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
123
124       When a new image is created this way all samples are set to zero -
125       black for 1 or 3 channel images, transparent black for 2 or 4 channel
126       images.
127
128       You can also create paletted images and images with more than 8-bits
129       per channel, see Imager::ImageTypes for more details.
130
131   Setting the background of a new image
132       To set the background of a new image to a solid color, use the box()
133       method with no limits, and "filled=>1":
134
135         $image->box(filled=>1, color=>$color);
136
137       As always, a color can be specified as an Imager::Color object:
138
139         my $white = Imager::Color->new(255, 255, 255);
140         $image->box(filled=>1, color=>$white);
141
142       or you supply any single scalar that Imager::Color's new() method
143       accepts as a color description:
144
145         $image->box(filled=>1, color=>'white');
146         $image->box(filled=>1, color=>'#FF0000');
147         $image->box(filled=>1, color=>[ 255, 255, 255 ]);
148
149       You can also fill the image with a fill object:
150
151         use Imager::Fill;
152         # create the fill object
153         my $fill = Imager::Fill->new(hatch=>'check1x1')
154         $image->box(fill=>$fill);
155
156         # let Imager create one automatically
157         $image->box(fill=>{ hatch=>'check1x1' });
158
159       See Imager::Fill for information on Imager's fill objects.
160

WORLD WIDE WEB

162       As with any CGI script it's up to you to validate data and set limits
163       on any parameters supplied to Imager.
164
165       For example, if you allow the caller to set the size of an output image
166       you should limit the size to prevent the client from specifying an
167       image size that will consume all available memory.
168
169       This is beside any other controls you need over access to data.
170
171       See CGI for a module useful for processing CGI submitted data.
172
173   Returning an image from a CGI script
174       This is similar to writing to a file, but you also need to supply the
175       information needed by the web browser to identify the file format:
176
177         my $img = ....; # create the image and generate the contents
178         ++$|; # make sure the content type isn't buffered
179         print "Content-Type: image/png\n\n";
180         binmode STDOUT;
181         $img->write(fd=>fileno(STDOUT), type=>'png')
182           or die $img->errstr;
183
184       You need to set the Content-Type header depending on the file format
185       you send to the web browser.
186
187       If you want to supply a content-length header, write the image to a
188       scalar as a buffer:
189
190         my $img = ....; # create the image and generate the contents
191         my $data;
192         $img->write(type=>'png', data=>\$data)
193           or die $img->errstr;
194         print "Content-Type: image/png\n";
195         print "Content-Length: ",length($data),"\n\n";
196         binmode STDOUT;
197         print $data;
198
199       See "samples/samp-scale.cgi" and "samples/samp-image.cgi" for a couple
200       of simple examples of producing an image from CGI.
201
202   Inserting a CGI image in a page
203       There's occasionally confusion on how to display an image generated by
204       Imager in a page generated by a CGI.
205
206       Your web browser handles this process as two requests, one for the HTML
207       page, and another for the image itself.
208
209       Each request needs to perform validation since an attacker can control
210       the values supplied to both requests.
211
212       How you make the data available to the image generation code depends on
213       your application.
214
215       See "samples/samp-form.cgi" and "samples/samp-image.cgi" in the Imager
216       distribution for one approach.  The POD in "samp-form.cgi" also
217       discusses some of the issues involved.
218
219   Parsing an image posted via CGI
220       "WARNING": file format attacks have become a common attack vector, make
221       sure you have up to date image file format libraries, otherwise trying
222       to parse uploaded files, whether with Imager or some other tool, may
223       result in a remote attacker being able to run their own code on your
224       system.
225
226       If your HTML form uses the correct magic, it can upload files to your
227       CGI script, in particular, you need to use " method="post" " and
228       "enctype="multipart/form-data"" in the "form" tag, and use
229       "type="file"" in the "input", for example:
230
231         <form action="/cgi-bin/yourprogram" method="post"
232               enctype="multipart/form-data">
233           <input type="file" name="myimage" />
234           <input type="submit value="Upload Image" />
235         </form>
236
237       To process the form:
238
239       1.  first check that the user supplied a file
240
241       2.  get the file handle
242
243       3.  have Imager read the image
244
245         # returns the client's name for the file, don't open this locally
246         my $cgi = CGI->new;
247         # 1. check the user supplied a file
248         my $filename = $cgi->param('myimage');
249         if ($filename) {
250           # 2. get the file handle
251           my $fh = $cgi->upload('myimage');
252           if ($fh) {
253             binmode $fh;
254
255             # 3. have Imager read the image
256             my $img = Imager->new;
257             if ($img->read(fh=>$fh)) {
258               # we can now process the image
259             }
260           }
261           # else, you probably have an incorrect form or input tag
262         }
263         # else, the user didn't select a file
264
265       See "samples/samp-scale.cgi" and "samples/samp-tags.cgi" in the Imager
266       distribution for example code.
267
268       You may also want to set limits on the size of the image read, using
269       Imager's "set_file_limits" method, documented in "set_file_limits()" in
270       Imager::Files.  For example:
271
272         # limit to 10 million bytes of memory usage
273         Imager->set_file_limits(bytes => 10_000_000);
274
275         # limit to 1024 x 1024
276         Imager->set_file_limits(width => 1024, height => 1024);
277

DRAWING

279   Adding a border to an image
280       First make a new image with space for the border:
281
282         my $border_width = ...;
283         my $border_height = ...;
284         my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
285                               ysize => $source->getheight() + 2 * $border_height,
286                               bits => $source->bits,
287                               channels => $source->getchannels);
288
289       Then paste the source image into the new image:
290
291         $out->paste(left => $border_width,
292                     top => $border_height,
293                     img => $source);
294
295       Whether you draw the border before or after pasting the original image
296       depends on whether you want the border to overlap the image, for
297       example a semi-transparent border drawn after pasting the source image
298       could overlap the edge without hiding it.
299
300       If you want a solid border you could just fill the image before pasting
301       the source for simplicity:
302
303         $out->box(filled=>1, color=>'red');
304         $out->paste(left => $border_width,
305                     top => $border_height,
306                     img => $source);
307

TEXT

309   Drawing text
310   Aligning text
311   Measuring text
312   Word wrapping text
313   Shearing (slanting) or Rotating text
314       This requires that you have Imager installed with FreeType 2.x support
315       installed, and that the font be created using the FreeType 2.x driver,
316       for example:
317
318         my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
319
320       First you need a transformation matrix, for shearing that could be:
321
322         my $angle_in_radians = ...;
323         my $tan_angle = sin($angle_rads) / cos($angle_rads);
324         # shear horizontally, supply this as y instead to do it vertically
325         my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
326
327       For rotation that would be:
328
329         my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
330
331       or:
332
333         my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
334
335       Feed that to the font object:
336
337         $font->transform(matrix => $matrix);
338
339       and draw the text as normal:
340
341         $image->string(string => $text,
342                        x => $where_x,
343                        y => $where_y,
344                        color => $color,
345                        font => $font);
346
347       See samples/slant_text.pl for a comprehensive example, including
348       calculating the transformed bounding box to create an image to fit the
349       transformed text into.
350

IMAGE TRANSFORMATION

352   Shearing an image
353   Convert to gray-scale
354       To convert an RGB image to a gray-scale image, use the convert method:
355
356         my $grey = $image->convert(preset => 'gray');
357
358       convert() returns a new image.
359
360       See: "Color transformations" in Imager::Transformations
361

METADATA

363   Image format
364       When Imager reads a file it does a magic number check to determine the
365       file type, so "foo.png" could actually be a GIF image, and Imager will
366       read it anyway.
367
368       You can check the actual format of the image by looking at the
369       "i_format" tag.
370
371         my $format = $image->tags(name=>'i_format');
372
373   Image spatial resolution
374       Most image file formats store information about the physical size of
375       the pixels, though in some cases that information isn't useful.
376
377       Imager stores this information in the tags "i_xres" and "i_yres", and
378       this is always stored in dots per inch.
379
380       Some formats, including TIFF and JPEG allow you to change the units
381       spatial resolution information is stored in, if you set the tag that
382       changes this the Imager will convert "i_xres" and "i_yres" to those
383       units when it writes the file.
384
385       For example to set the resolution to 300 dpi:
386
387         $image->settag(name => 'i_xres', value => 300);
388         $image->settag(name => 'i_yres', value => 300);
389
390       If you want the file format to store the resolution in some other unit,
391       for example you can write a TIFF file that stores the resolution in
392       pixels per centimeter, you would do:
393
394         # 150 pixels/cm
395         $image->settag(name => 'i_xres', value => 150 * 2.54);
396         $image->settag(name => 'i_yres', value => 150 * 2.54);
397         $image->settag(name => 'tiff_resolutionunit', value => 3);
398
399       Keywords: DPI
400

IMAGE MANIPULATION

402   Replacing a color with transparency
403       To replace a color with transparency you can use the "difference()" in
404       Imager::Filters method.
405
406         # make a work image the same size as our input
407         my $work = Imager->new(xsize => $in->getwidth, ysize => $in->getheight,
408                                channels => $in->getchannels);
409         # and fill it with the color we want transparent
410         $work->box(filled => 1, color => $color);
411
412         # get an image with that color replaced with transparent black
413         my $out = $work->difference(other => $in);
414

SPECIAL EFFECTS

416   Drop Shadows
417       This can be used for a glow effect as well.
418
419       First create a new image, either with an alpha channel (if you want
420       transparency behind the shadow) or without, if you want a background
421       color:
422
423         my $out = Imager->new
424            (
425            xsize => $shadow_size * 2 + $src->getwidth,
426            ysize => $shadow_size * 2 + $src->getheight,
427            channels => 4,
428            );
429         # fill it with your background color, if you want one
430         # $out->box(filled => 1, color => $back_color);
431
432       Make a work image to render the shadow on:
433
434         my $shadow_work = Imager->new
435           (
436           xsize => $back->getwidth,
437           ysize => $back->getheight,
438           channels => 1,
439           );
440
441       Extract the alpha channel from the source image, first the alpha
442       version:
443
444         my $alpha = $src->convert(preset => "alpha");
445
446       and draw that on the work shadow:
447
448         $shadow_work->paste
449           (
450           src => $slpha,
451           left => $shadow_size,
452           top => $shadow_size,
453           );
454
455       otherwise just draw a box for the non-alpha source:
456
457         $shadow_work->box
458           (
459           filled => 1,
460           color => [ 255 ],
461           xmin => $shadow_size,
462           ymin => $shadow_size,
463           xmax => $shadow_size + $src->getwidth() - 1,
464           ymax => $shadow_size + $src->getheight() - 1,
465           );
466
467       Blur the work shadow:
468
469         $shadow_work->filter(type => "gaussian", stddev => $shadow_size);
470
471       Convert it to an RGB image with alpha:
472
473         $shadow_work = $shadow_work->convert
474            (
475             matrix => [ [ 0, $red / 255 ],
476                          [ 0, $green / 255 ],
477                          [ 0, $blue / 255 ],
478                          [ 1 ] ]
479            );
480
481       Draw that on the output image:
482
483         $out->rubthrough(src => $shadow_work);
484
485       Draw our original image on the output image, perhaps with an offset:
486
487         $out->rubthrough
488           (
489           src => $src,
490           tx => $shadow_size + $x_offset,
491           ty => $shadow_size + $y_offset,
492           );
493
494       See samples/drop_shadow.pl for an example of this recipe.
495

AUTHOR

497       Tony Cook <tony@develop-help.com>
498

SEE ALSO

500       Imager, Imager::Files, Imager::Draw.
501
502
503
504perl v5.32.0                      2020-07-28               Imager::Cookbook(3)
Impressum