File Coverage

blib/lib/Imager/Montage.pm
Criterion Covered Total %
statement 9 68 13.2
branch 0 16 0.0
condition 0 24 0.0
subroutine 3 9 33.3
pod 2 2 100.0
total 14 119 11.7


line stmt bran cond sub pod time code
1             package Imager::Montage;
2              
3 1     1   34538 use warnings;
  1         3  
  1         40  
4 1     1   49 use strict;
  1         2  
  1         39  
5              
6 1     1   6837 use Imager;
  1         50442  
  1         7  
7              
8             =head1 NAME
9              
10             Imager::Montage - montage images
11              
12             =head1 VERSION
13              
14             Version 0.01
15              
16             =cut
17              
18             our $VERSION = '0.02';
19              
20             =head1 SYNOPSIS
21              
22             # Generate a montage image.
23              
24             use Imager::Montage;
25              
26             my $im = Imager::Montage->new;
27             my @imgs = <*.png>;
28             my $page = $im->gen_page(
29             {
30             files => \@imgs,
31             geometry_w => 200, # geometry from source. if not set , the resize_w , resize_h will be the default
32             geometry_h => 200, # if we aren't going to resize the source images , we should specify the geometry at least.
33             cols => 5,
34             rows => 5,
35             }
36             );
37             $page->write( file => 'page.png' , type => 'png' ); # generate a 1000x1000 pixels image with 5x5 tiles
38              
39             =head1 EXPORT
40              
41              
42             =head1 Methods
43              
44             =over 4
45              
46             =item B
47             =cut
48              
49             sub new {
50 0     0 1   my $class = shift;
51 0           return bless {}, $class;
52             }
53              
54              
55             =item B<_load_image>
56              
57             return a Imager object
58              
59             $imager = $self->_load_image( $filename );
60              
61             =cut
62              
63             sub _load_image {
64 0     0     my $self = shift;
65 0           my $filename = shift;
66 0           my $o = Imager->new;
67 0           $o->read( file => $filename );
68 0           return $o;
69             }
70              
71             =item B<_load_font>
72            
73             Return Imager::Font
74              
75             my $font = _load_font( { file => '/path/to/font.ttf' , color => '#000000' , size => 72 } );
76              
77             =cut
78              
79             sub _load_font {
80 0     0     my ( $self , $args ) = @_;
81             # get the font path
82 0           my $color = Imager::Color->new( $args->{color} );
83 0           my $font = Imager::Font->new(
84             file => $args->{file},
85             color => Imager::Color->new( $args->{color} ),
86             size => $args->{size},
87             );
88 0           return $font;
89             }
90              
91             =item B<_load_color>
92            
93             return Imager::Color
94              
95             $self->_load_color( '#000000' );
96              
97             =cut
98              
99             sub _load_color {
100 0     0     my ( $self , $color ) = @_;
101 0           return Imager::Color->new( $color ),
102             }
103              
104             =item B
105              
106             montage your source image . it will return an Imager Object.
107              
108             my $page = $im->gen_page(
109             {
110             files => \@imgs,
111             resize_w => 100,
112             resize_h => 100,
113             cols => 3,
114             rows => 3,
115             margin_v => 5,
116             margin_h => 5,
117              
118             page_width => 800,
119             page_height => 600,
120             background_color => '#ffffff',
121              
122             flip => 'h', # horizontal flip
123             flip_exclude => ' return $file =~ m/d\d+.png/ '
124             , # don't flip files named \d+.png ( optional )
125              
126             frame => 4, # ( optional )
127             frame_color => '#000000',
128              
129             border => 4,
130             border_color => '#000000',
131              
132             res => 600,
133             }
134             );
135              
136             Parameters:
137              
138             I: an array contains filenames
139              
140             I: background color of output image
141              
142             I: geometry from source. if not set , the resize_w , resize_h will be the default
143              
144             I): if it's given , montage will resize your source image to this size
145              
146             I: tiles
147              
148             I: margin for each image
149              
150             I: the output image width & height
151              
152             I: do flip to each source image
153              
154             I
155              
156             I: frame width (optional)
157              
158             I: frame color (optional)
159              
160             I: border width for each image (optional)
161              
162             I: border color (optional)
163              
164             I: resolution , default resolution is 600 (optional)
165              
166             =cut
167              
168             # XXX: calculates the max cols and max rows if we specify the page width and page height
169             sub gen_page {
170 0     0 1   my $self = shift;
171 0           my $args = shift;
172              
173 0   0       $args->{geometry_w} ||= $args->{resize_w};
174 0   0       $args->{geometry_h} ||= $args->{resize_h};
175              
176             $args->{$_} ||= 0
177 0   0       for(qw/border frame margin_v margin_h/);
178              
179             $args->{$_} ||= '#ffffff'
180 0   0       for (qw/background_color border_color frame_color/);
181              
182 0   0       $args->{page_width}
183             ||= $args->{frame} * 2
184             + ( $args->{border} * 2 ) * $args->{cols}
185             + $args->{geometry_w} * $args->{cols}
186             + ( $args->{margin_h} * 2 ) * $args->{cols};
187              
188 0   0       $args->{page_height}
189             ||= $args->{frame} * 2
190             + ( $args->{border} * 2 ) * $args->{rows}
191             + $args->{geometry_h} * $args->{rows}
192             + ( $args->{margin_v} * 2 ) * $args->{rows};
193              
194              
195             $args->{$_} = $self->_load_color( $args->{$_} )
196 0           for (qw/background_color border_color frame_color/);
197              
198             # create a page
199 0           my $page_img = Imager->new(
200             xsize => $args->{page_width},
201             ysize => $args->{page_height});
202              
203 0 0         $self->_set_resolution( $page_img, $args->{res} )
204             if ( exists $args->{res} );
205              
206             # this could make a frame for page
207 0 0         if ( exists $args->{frame} ) {
208 0           $page_img->box(
209             filled => 1,
210             color => $args->{frame_color} );
211              
212 0           my $box = Imager->new(
213             xsize => $args->{page_width} - $args->{frame} * 2 ,
214             ysize => $args->{page_height} - $args->{frame} * 2 )->box( filled => 1, color => $args->{background_color});
215              
216 0           $page_img->paste(
217             left => $args->{frame},
218             top => $args->{frame},
219             src => $box);
220             }
221             else {
222 0           $page_img->box(
223             filled => 1,
224             color => $args->{background_color},
225             );
226             }
227              
228 0           my ( $top, $left ) = (
229             $args->{frame},
230             $args->{frame} );
231              
232 0           for my $col ( 0 .. $args->{cols} - 1 ) {
233              
234 0           $top = $args->{frame};
235              
236 0           for my $row ( 0 .. $args->{rows} - 1 ) {
237              
238             # get filename
239 0           my $file = ${ $args->{files} }[ $col * $args->{rows} + $row ];
  0            
240 0 0         next if ( ! defined $file );
241              
242              
243 0           my $canvas_img = $self->_load_image($file);
244              
245             # resize it if we define a new size
246 0 0         if ( exists $args->{resize_w} ) {
247 0           $canvas_img = $canvas_img->scale(
248             xpixels => $args->{resize_w},
249             ypixels => $args->{resize_h},
250             type => 'nonprop',); } # XXX: make nonprop as parameter
251              
252             # flip
253 0 0 0       if ( exists $args->{flip}
      0        
254             and ( exists $args->{flip_exclude} and !eval( $args->{flip_exclude} ) ) ) {
255 0           $canvas_img->flip( dir => $args->{flip} ); }
256              
257             # if border is set
258 0 0         if( $args->{border} ) {
259             # gen border , paste it before we paste image to the page
260 0           my $box = Imager->new(
261             xsize => $args->{geometry_w} + $args->{border} * 2,
262             ysize => $args->{geometry_h} + $args->{border} * 2 )->box( filled => 1, color => $args->{border_color} );
263 0           $page_img->paste(
264             left => $left + $args->{margin_h} ,
265             top => $top + $args->{margin_v} ,
266             src => $box );
267             }
268              
269             $page_img->paste(
270 0           left => $left + $args->{margin_h} + $args->{border} , # default border is 0
271             top => $top + $args->{margin_v} + $args->{border} ,
272             src => $canvas_img);
273              
274             } continue {
275 0           $top += ( $args->{border} * 2 + $args->{margin_v} * 2 + $args->{geometry_h} );
276             }
277             }
278             continue {
279 0           $left += ( $args->{border} * 2 + $args->{margin_h} * 2 + $args->{geometry_w} );
280             }
281              
282 0           return $page_img;
283             }
284              
285             =item B<_set_resolution>
286              
287             default resolution is 600 dpi
288              
289             $self->_set_resolution( $filename , 600 );
290             $self->_set_resolution( $imager );
291              
292             =cut
293              
294             sub _set_resolution {
295 0     0     my $self = shift;
296 0           my $src = shift;
297 0   0       my $res = shift || 600;
298 0 0         if ( $src =~ m/^Imager::/ ) {
    0          
299              
300             # use Imager to set resolution
301 0           $src->settag( name => 'i_xres', value => $res );
302 0           $src->settag( name => 'i_yres', value => $res );
303             }
304             elsif ( ref($src) eq 'SCALAR' ) {
305              
306             # it's a filename
307 0           my $image = Imager->new();
308 0           $image->read( file => $src ); # read from file
309 0           $image->settag( name => 'i_xres', value => $res );
310 0           $image->settag( name => 'i_yres', value => $res );
311 0           $image->write( file => $src, type => 'png' ); # write to reference
312             }
313             }
314              
315             =back
316              
317             =head1 AUTHOR
318              
319             Cornelius, C<< >>
320              
321             =head1 BUGS
322              
323             Please report any bugs or feature requests to C, or through
324             the web interface at L. I will be notified, and then you'll
325             automatically be notified of progress on your bug as I make changes.
326              
327             =head1 SUPPORT
328              
329             You can find documentation for this module with the perldoc command.
330              
331             perldoc Imager::Montage
332              
333             You can also look for information at:
334              
335             =over 4
336              
337             =item * RT: CPAN's request tracker
338              
339             L
340              
341             =item * AnnoCPAN: Annotated CPAN documentation
342              
343             L
344              
345             =item * CPAN Ratings
346              
347             L
348              
349             =item * Search CPAN
350              
351             L
352              
353             =back
354              
355              
356             =head1 ACKNOWLEDGEMENTS
357              
358              
359             =head1 COPYRIGHT & LICENSE
360              
361             Copyright 2007 Cornelius, all rights reserved.
362              
363             This program is free software; you can redistribute it and/or modify it
364             under the same terms as Perl itself.
365              
366              
367             =cut
368              
369             1; # End of Imager::Montage