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
161   Create an image from raw RGB data
162       If your data matches the layout supported by Imager's "RAW" in
163       Imager::Files file support closely enough, you can simply read the data
164       as if it was a raw file:
165
166         my $img = Imager->new(
167           (
168            filetype => "raw",
169            xsize => $width,
170            ysize => $height,
171            # stored as RGBXRGBX where X is dropped
172            raw_interleave => 0,
173            raw_datachannels => 4,
174            raw_storechannels => 3,
175           );
176
177       If the channel order doesn't match you can further use the "combine()"
178       in Imager::Transformations method to extract the channels in the
179       correct order, eg. if the source data above was in "BGRX" format
180       instead of "RGBX":
181
182         my $img2 = $im->combine(src      => [ $img, $img, $img ],
183                                 channels => [ 2,    1,    0    ]);
184
185       Adapted from perl monks <https://perlmonks.org/?node_id=11139983>.
186
187       For more control you can use the setsamples() method to set pixels
188       directly to the image:
189
190         # for AGBR data in $data
191         my $img = Imager->new(xsize => $width, ysize => $height, channels => 4);
192         my $rowbytes = $width * 4;
193         my @chans = [ 3, 1, 2, 0 ];
194         for my $row (0 .. $height) {
195           $img->setsamples
196             (
197             y => $row,
198             data => $data,
199             offset => $rowbytes * $row,
200             channels => \@chans,
201             type => '8bit',
202             );
203         }
204

WORLD WIDE WEB

206       As with any CGI script it's up to you to validate data and set limits
207       on any parameters supplied to Imager.
208
209       For example, if you allow the caller to set the size of an output image
210       you should limit the size to prevent the client from specifying an
211       image size that will consume all available memory.
212
213       This is beside any other controls you need over access to data.
214
215       See CGI for a module useful for processing CGI submitted data.
216
217   Returning an image from a CGI script
218       This is similar to writing to a file, but you also need to supply the
219       information needed by the web browser to identify the file format:
220
221         my $img = ....; # create the image and generate the contents
222         ++$|; # make sure the content type isn't buffered
223         print "Content-Type: image/png\n\n";
224         binmode STDOUT;
225         $img->write(fd=>fileno(STDOUT), type=>'png')
226           or die $img->errstr;
227
228       You need to set the Content-Type header depending on the file format
229       you send to the web browser.
230
231       If you want to supply a content-length header, write the image to a
232       scalar as a buffer:
233
234         my $img = ....; # create the image and generate the contents
235         my $data;
236         $img->write(type=>'png', data=>\$data)
237           or die $img->errstr;
238         print "Content-Type: image/png\n";
239         print "Content-Length: ",length($data),"\n\n";
240         binmode STDOUT;
241         print $data;
242
243       See "samples/samp-scale.cgi" and "samples/samp-image.cgi" for a couple
244       of simple examples of producing an image from CGI.
245
246   Inserting a CGI image in a page
247       There's occasionally confusion on how to display an image generated by
248       Imager in a page generated by a CGI.
249
250       Your web browser handles this process as two requests, one for the HTML
251       page, and another for the image itself.
252
253       Each request needs to perform validation since an attacker can control
254       the values supplied to both requests.
255
256       How you make the data available to the image generation code depends on
257       your application.
258
259       See "samples/samp-form.cgi" and "samples/samp-image.cgi" in the Imager
260       distribution for one approach.  The POD in "samp-form.cgi" also
261       discusses some of the issues involved.
262
263   Parsing an image posted via CGI
264       "WARNING": file format attacks have become a common attack vector, make
265       sure you have up to date image file format libraries, otherwise trying
266       to parse uploaded files, whether with Imager or some other tool, may
267       result in a remote attacker being able to run their own code on your
268       system.
269
270       If your HTML form uses the correct magic, it can upload files to your
271       CGI script, in particular, you need to use " method="post" " and
272       "enctype="multipart/form-data"" in the "form" tag, and use
273       "type="file"" in the "input", for example:
274
275         <form action="/cgi-bin/yourprogram" method="post"
276               enctype="multipart/form-data">
277           <input type="file" name="myimage" />
278           <input type="submit value="Upload Image" />
279         </form>
280
281       To process the form:
282
283       1.  first check that the user supplied a file
284
285       2.  get the file handle
286
287       3.  have Imager read the image
288
289         # returns the client's name for the file, don't open this locally
290         my $cgi = CGI->new;
291         # 1. check the user supplied a file
292         my $filename = $cgi->param('myimage');
293         if ($filename) {
294           # 2. get the file handle
295           my $fh = $cgi->upload('myimage');
296           if ($fh) {
297             binmode $fh;
298
299             # 3. have Imager read the image
300             my $img = Imager->new;
301             if ($img->read(fh=>$fh)) {
302               # we can now process the image
303             }
304           }
305           # else, you probably have an incorrect form or input tag
306         }
307         # else, the user didn't select a file
308
309       See "samples/samp-scale.cgi" and "samples/samp-tags.cgi" in the Imager
310       distribution for example code.
311
312       You may also want to set limits on the size of the image read, using
313       Imager's "set_file_limits" method, documented in "set_file_limits()" in
314       Imager::Files.  For example:
315
316         # limit to 10 million bytes of memory usage
317         Imager->set_file_limits(bytes => 10_000_000);
318
319         # limit to 1024 x 1024
320         Imager->set_file_limits(width => 1024, height => 1024);
321

DRAWING

323   Adding a border to an image
324       First make a new image with space for the border:
325
326         my $border_width = ...;
327         my $border_height = ...;
328         my $out = Imager->new(xsize => $source->getwidth() + 2 * $border_width,
329                               ysize => $source->getheight() + 2 * $border_height,
330                               bits => $source->bits,
331                               channels => $source->getchannels);
332
333       Then paste the source image into the new image:
334
335         $out->paste(left => $border_width,
336                     top => $border_height,
337                     img => $source);
338
339       Whether you draw the border before or after pasting the original image
340       depends on whether you want the border to overlap the image, for
341       example a semi-transparent border drawn after pasting the source image
342       could overlap the edge without hiding it.
343
344       If you want a solid border you could just fill the image before pasting
345       the source for simplicity:
346
347         $out->box(filled=>1, color=>'red');
348         $out->paste(left => $border_width,
349                     top => $border_height,
350                     img => $source);
351

TEXT

353   Drawing text
354   Aligning text
355   Measuring text
356   Word wrapping text
357   Shearing (slanting) or Rotating text
358       This requires that you have Imager installed with FreeType 2.x support
359       installed, and that the font be created using the FreeType 2.x driver,
360       for example:
361
362         my $font = Imager::Font->new(file=>$fontfile, type=>'ft2');
363
364       First you need a transformation matrix, for shearing that could be:
365
366         my $angle_in_radians = ...;
367         my $tan_angle = sin($angle_rads) / cos($angle_rads);
368         # shear horizontally, supply this as y instead to do it vertically
369         my $matrix = Imager::Matrix2d->shear(x=>$tan_angle);
370
371       For rotation that would be:
372
373         my $matrix = Imager::Matrix2d->rotate(radians => $angle_in_radians);
374
375       or:
376
377         my $matrix = Imager::Matrix2d->rotate(degrees => $angle_in_degrees);
378
379       Feed that to the font object:
380
381         $font->transform(matrix => $matrix);
382
383       and draw the text as normal:
384
385         $image->string(string => $text,
386                        x => $where_x,
387                        y => $where_y,
388                        color => $color,
389                        font => $font);
390
391       See samples/slant_text.pl for a comprehensive example, including
392       calculating the transformed bounding box to create an image to fit the
393       transformed text into.
394

IMAGE TRANSFORMATION

396   Shearing an image
397   Convert to gray-scale
398       To convert an RGB image to a gray-scale image, use the convert method:
399
400         my $grey = $image->convert(preset => 'gray');
401
402       convert() returns a new image.
403
404       See: "Color transformations" in Imager::Transformations
405

METADATA

407   Image format
408       When Imager reads a file it does a magic number check to determine the
409       file type, so "foo.png" could actually be a GIF image, and Imager will
410       read it anyway.
411
412       You can check the actual format of the image by looking at the
413       "i_format" tag.
414
415         my $format = $image->tags(name=>'i_format');
416
417   Image spatial resolution
418       Most image file formats store information about the physical size of
419       the pixels, though in some cases that information isn't useful.
420
421       Imager stores this information in the tags "i_xres" and "i_yres", and
422       this is always stored in dots per inch.
423
424       Some formats, including TIFF and JPEG allow you to change the units
425       spatial resolution information is stored in, if you set the tag that
426       changes this the Imager will convert "i_xres" and "i_yres" to those
427       units when it writes the file.
428
429       For example to set the resolution to 300 dpi:
430
431         $image->settag(name => 'i_xres', value => 300);
432         $image->settag(name => 'i_yres', value => 300);
433
434       If you want the file format to store the resolution in some other unit,
435       for example you can write a TIFF file that stores the resolution in
436       pixels per centimeter, you would do:
437
438         # 150 pixels/cm
439         $image->settag(name => 'i_xres', value => 150 * 2.54);
440         $image->settag(name => 'i_yres', value => 150 * 2.54);
441         $image->settag(name => 'tiff_resolutionunit', value => 3);
442
443       Keywords: DPI
444

IMAGE MANIPULATION

446   Replacing a color with transparency
447       To replace a color with transparency you can use the "difference()" in
448       Imager::Filters method.
449
450         # make a work image the same size as our input
451         my $work = Imager->new(xsize => $in->getwidth, ysize => $in->getheight,
452                                channels => $in->getchannels);
453         # and fill it with the color we want transparent
454         $work->box(filled => 1, color => $color);
455
456         # get an image with that color replaced with transparent black
457         my $out = $work->difference(other => $in);
458

SPECIAL EFFECTS

460   Drop Shadows
461       This can be used for a glow effect as well.
462
463       First create a new image, either with an alpha channel (if you want
464       transparency behind the shadow) or without, if you want a background
465       color:
466
467         my $out = Imager->new
468            (
469            xsize => $shadow_size * 2 + $src->getwidth,
470            ysize => $shadow_size * 2 + $src->getheight,
471            channels => 4,
472            );
473         # fill it with your background color, if you want one
474         # $out->box(filled => 1, color => $back_color);
475
476       Make a work image to render the shadow on:
477
478         my $shadow_work = Imager->new
479           (
480           xsize => $back->getwidth,
481           ysize => $back->getheight,
482           channels => 1,
483           );
484
485       Extract the alpha channel from the source image, first the alpha
486       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 samples/drop_shadow.pl for an example of this recipe.
539

AUTHOR

541       Tony Cook <tony@develop-help.com>
542

SEE ALSO

544       Imager, Imager::Files, Imager::Draw.
545
546
547
548perl v5.36.0                      2022-07-22               Imager::Cookbook(3)
Impressum