]> git.imager.perl.org - imager.git/blob - lib/Imager/Cookbook.pod
CGI samples
[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 =head1 IMAGE SYNTHESIS
48
49 =head2 Creating an image
50
51 To create a simple RGB image, supply the image width and height to the
52 new() method:
53
54   my $rgb = Imager->new(xsize=>$width, ysize=>$height);
55
56 If you also want an alpha channel:
57
58   my $rgb_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>4);
59
60 To make a grayscale image:
61
62   my $gray = Imager->new(xsize=>$width, ysize=>$height, channels=>1);
63
64 and a grayscale image with an alpha channel:
65
66   my $gray_alpha = Imager->new(xsize=>$width, ysize=>$height, channels=>2);
67
68 When a new image is created this way all samples are set to zero -
69 black for 1 or 3 channel images, transparent black for 2 or 4 channel
70 images.
71
72 You can also create paletted images and images with more than 8-bits
73 per channel, see L<Imager::ImageTypes> for more details.
74
75 =head2 Setting the background of a new image
76
77 To set the background of a new image to a solid color, use the box()
78 method with no limits, and C<< filled=>1 >>:
79
80   $image->box(filled=>1, color=>$color);
81
82 As always, a color can be specified as an L<Imager::Color> object:
83
84   my $white = Imager::Color->new(255, 255, 255);
85   $image->box(filled=>1, color=>$white);
86
87 or you supply any single scalar that Imager::Color's new() method
88 accepts as a color description:
89
90   $image->box(filled=>1, color=>'white');
91   $image->box(filled=>1, color=>'#FF0000');
92   $image->box(filled=>1, color=>[ 255, 255, 255 ]);
93
94 You can also fill the image with a fill object:
95
96   use Imager::Fill;
97   # create the fill object
98   my $fill = Imager::Fill->new(hatch=>'check1x1')
99   $image->box(fill=>$fill);
100
101   # let Imager create one automatically
102   $image->box(fill=>{ hatch=>'check1x1' });
103
104 See L<Imager::Fill> for information on Imager's fill objects.
105
106 =head1 WORLD WIDE WEB
107
108 As with any CGI script it's up to you to validate data and set limits
109 on any parameters supplied to Imager.
110
111 For example, if you allow the caller to set the size of an output
112 image you should limit the size to prevent the client from specifying
113 an image size that will consume all available memory.
114
115 This is beside any any other controls you need over access to data.
116
117 See L<CGI> for a module useful for processing CGI submitted data.
118
119 =head2 Returning an image from a CGI script
120
121 This is similar to writing to a file, but you also need to supply the
122 information needed by the web browser to identify the file format:
123
124   my $img = ....; # create the image and generate the contents
125   print "Content-Type: image/png\n\n";
126   binmode STDOUT;
127   $img->write(fd=>fileno(STDOUT), type=>'png')
128     or die $img->errstr;
129
130 You need to set the Content-Type header depending on the file format
131 you send to the web browser.
132
133 If you want to supply a content-length header, write the image to a
134 scalar as a buffer:
135
136   my $img = ....; # create the image and generate the contents
137   my $data;
138   $img->write(type=>'png', data=>\$data)
139     or die $img->errstr;
140   print "Content-Type: image/png\n";
141   print "Content-Length: ",length($data),"\n\n";
142   binmode STDOUT;
143   print $data;
144
145 =head2 Inserting a CGI image in a page
146
147 There's occasionally confusion on how to display an image generated by
148 Imager in a page generated by a CGI.
149
150 Your web browser handles this process as two requests, one for the
151 HTML page, and another for the image itself.
152
153 Each request needs to perform validation since an attacker can control
154 the values supplied to both requests.
155
156 How you make the data available to the image generation code depends
157 on your application.
158
159 =head2 Parsing an image posted via CGI
160
161 C<WARNING>: file format attacks have become a common attack vector,
162 make sure you have up to date image file format libraries, otherwise
163 trying to parse uploaded files, whether with Imager or some other
164 tool, may result in a remote attacker being able to run their own code
165 on your system.  Currently Imager makes no attempt to place size
166 limits on a read image file.  This may result in consumption of large
167 amounts of memory.  Future versions of Imager may provide mechanisms
168 to limit the sizes of images read from files.
169
170 If your HTML form uses the correct magic, it can upload files to your
171 CGI script, in particular, you need to use C< method="post" > and
172 C<enctype="multipart/form-data"> in the C<form> tag, and use
173 C<type="file"> in the C<input>, for example:
174
175   <form action="/cgi-bin/yourprogram" method="post" 
176         enctype="multipart/form-data">
177     <input type="file" name="myimage" />
178     <input type="submit value="Upload Image" />
179   </form>
180
181 To process the form:
182
183 =over
184
185 =item 1.
186
187 first check that the user supplied a file
188
189 =item 2.
190
191 get the file handle
192
193 =item 3.
194
195 have Imager read the image
196
197 =back
198
199   # returns the client's name for the file, don't open this locally
200   my $cgi = CGI->new;
201   # 1. check the user supplied a file
202   my $filename = $cgi->param('myimage');
203   if ($filename) {
204     # 2. get the file handle
205     my $fh = $cgi->upload('myimage');
206     if ($fh) {
207       binmode $fh;
208       
209       # 3. have Imager read the image
210       my $img = Imager->new;
211       if ($img->read(fh=>$fh)) {
212         # we can now process the image
213       }
214     }
215     # else, you probably have an incorrect form or input tag
216   }
217   # else, the user didn't select a file
218
219 =head1 DRAWING
220
221 =head1 TEXT
222
223 =head2 Drawing text
224
225 =head2 Aligning text
226
227 =head2 Measuring text
228
229 =head2 Word wrapping text
230
231 =head1 METADATA
232
233 =head2 Image spatial resolution.
234
235 Keywords: DPI
236
237 =head1 AUTHOR
238
239 Tony Cook <tony@develop-help.com>
240
241 =head1 SEE ALSO
242
243 L<Imager>, L<Imager::Files>, L<Imager::Draw>.
244
245 =cut