File Coverage

blib/lib/Image/Magick/Tiler.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Image::Magick::Tiler;
2              
3             # Name:
4             # Image::Magick::Slice.
5             #
6             # Documentation:
7             # POD-style documentation is at the end. Extract it with pod2html.*.
8             #
9             # Reference:
10             # Object Oriented Perl
11             # Damian Conway
12             # Manning
13             # 1-884777-79-1
14             # P 114
15             #
16             # Note:
17             # o Tab = 4 spaces || die.
18             #
19             # Author:
20             # Ron Savage
21             # Home page: http://savage.net.au/index.html
22             #
23             # Licence:
24             # Australian copyright (c) 1999-2002 Ron Savage.
25             #
26             # All Programs of mine are 'OSI Certified Open Source Software';
27             # you can redistribute them and/or modify them under the terms of
28             # The Artistic License, a copy of which is available at:
29             # http://www.opensource.org/licenses/index.html
30              
31 1     1   21658 use strict;
  1         2  
  1         36  
32 1     1   5 use warnings;
  1         2  
  1         25  
33              
34 1     1   5 use Carp;
  1         2  
  1         123  
35 1     1   5 use File::Spec;
  1         1  
  1         24  
36 1     1   395 use Image::Magick;
  0            
  0            
37              
38             require 5.005_62;
39              
40             require Exporter;
41              
42             our @ISA = qw(Exporter);
43              
44             # Items to export into callers namespace by default. Note: do not export
45             # names by default without a very good reason. Use EXPORT_OK instead.
46             # Do not simply export all your public functions/methods/constants.
47              
48             # This allows declaration use Image::Magick::Tiler ':all';
49             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
50             # will save memory.
51             our %EXPORT_TAGS = ( 'all' => [ qw(
52              
53             ) ] );
54              
55             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
56              
57             our @EXPORT = qw(
58              
59             );
60             our $VERSION = '1.03';
61              
62             # -----------------------------------------------
63              
64             # Preloaded methods go here.
65              
66             # -----------------------------------------------
67              
68             # Encapsulated class data.
69              
70             {
71             my(%_attr_data) =
72             (
73             _input_file => '',
74             _geometry => '2x2+0+0',
75             _output_dir => '',
76             _output_type => 'png',
77             _return => 1,
78             _verbose => 0,
79             _write => 0,
80             );
81              
82             sub _default_for
83             {
84             my($self, $attr_name) = @_;
85              
86             $_attr_data{$attr_name};
87             }
88              
89             sub _standard_keys
90             {
91             keys %_attr_data;
92             }
93              
94             } # End of encapsulated class data.
95              
96             # -----------------------------------------------
97              
98             sub new
99             {
100             my($caller, %arg) = @_;
101             my($caller_is_obj) = ref($caller);
102             my($class) = $caller_is_obj || $caller;
103             my($self) = bless({}, $class);
104              
105             for my $attr_name ($self -> _standard_keys() )
106             {
107             my($arg_name) = $attr_name =~ /^_(.*)/;
108              
109             if (exists($arg{$arg_name}) )
110             {
111             $$self{$attr_name} = $arg{$arg_name};
112             }
113             elsif ($caller_is_obj)
114             {
115             $$self{$attr_name} = $$caller{$attr_name};
116             }
117             else
118             {
119             $$self{$attr_name} = $self -> _default_for($attr_name);
120             }
121             }
122              
123             Carp::croak("Error. You must call new as new(input_file => 'some file'). ") if (! $$self{'_input_file'});
124              
125             my($g) = $$self{'_geometry'};
126              
127             if ($g =~ /^(\d*)(x?)(\d*)([+-]?\d*)([+-]?\d*)$/i)
128             {
129             $$self{'_geometry'} = [$1, $2, $3, $4, $5];
130             $$self{'_geometry'}[0] = 2 if ($$self{'_geometry'}[0] eq '');
131             $$self{'_geometry'}[1] = 'x' if ($$self{'_geometry'}[1] eq '');
132             $$self{'_geometry'}[2] = 2 if ($$self{'_geometry'}[2] eq '');
133             $$self{'_geometry'}[3] = '+0' if ($$self{'_geometry'}[3] =~ /^(|\+|-)$/);
134             $$self{'_geometry'}[4] = '+0' if ($$self{'_geometry'}[4] =~ /^(|\+|-)$/);
135              
136             Carp::croak("Error. Input (NxM+x+y = $g) specifies N = 0") if ($$self{'_geometry'}[0] =~ /^0+$/);
137             Carp::croak("Error. Input (NxM+x+y = $g) specifies M = 0") if ($$self{'_geometry'}[2] =~ /^0+$/);
138              
139             if ($$self{'_verbose'})
140             {
141             print "Image::Magick: V $Image::Magick::VERSION. \n";
142             print "Image::Magick::Tiler: V $Image::Magick::Tiler::VERSION. \n";
143             print "Geometry: $g parsed as NxM+x+y = " . join('', @{$$self{'_geometry'} }) . ". \n";
144             }
145             }
146             else
147             {
148             Carp::croak("Error. Input (NxM+x+y = $g) is not in the correct format. ");
149             }
150              
151             return $self;
152              
153             } # End of new.
154              
155             # -----------------------------------------------
156              
157             sub tile
158             {
159             my($self) = @_;
160             my($image) = Image::Magick -> new();
161             my($result) = $image -> Read($$self{'_input_file'});
162              
163             Carp::croak("Error. Unable to read file $$self{'_input_file'}. Image::Magick error: $result. ") if ($result);
164              
165             my($param) = {};
166             $$param{'image'} = {};
167             ($$param{'image'}{'width'}, $$param{'image'}{'height'}) = $image -> Get('width', 'height');
168              
169             $$param{'tile'} = {};
170             $$param{'tile'}{'width'} = int($$param{'image'}{'width'} / $$self{'_geometry'}[0]);
171             $$param{'tile'}{'height'} = int($$param{'image'}{'height'} / $$self{'_geometry'}[2]);
172              
173             if ($$self{'_verbose'})
174             {
175             print "Image: $$self{'_input_file'}. \n";
176             print "Image size: ($$param{'image'}{'width'}, $$param{'image'}{'height'}). \n";
177             print "Tile size: ($$param{'tile'}{'width'}, $$param{'tile'}{'height'}) (before applying x and y). \n";
178             }
179              
180             Carp::croak("Error. Tile width ($$param{'tile'}{'width'}) < input x ($$self{'_geometry'}[3]). ") if ($$param{'tile'}{'width'} < abs($$self{'_geometry'}[3]) );
181             Carp::croak("Error. Tile height ($$param{'tile'}{'height'}) < input y ($$self{'_geometry'}[4]). ") if ($$param{'tile'}{'height'} < abs($$self{'_geometry'}[4]) );
182              
183             $$param{'tile'}{'width'} += $$self{'_geometry'}[3];
184             $$param{'tile'}{'height'} += $$self{'_geometry'}[4];
185              
186             if ($$self{'_verbose'})
187             {
188             print "Tile size: ($$param{'tile'}{'width'}, $$param{'tile'}{'height'}) (after applying x and y). \n";
189             }
190              
191             my($output) = [];
192             my($x) = 0;
193              
194             my($y, $tile, $output_file_name);
195              
196             for my $xg (1 .. $$self{'_geometry'}[0])
197             {
198             $y = 0;
199              
200             for my $yg (1 .. $$self{'_geometry'}[2])
201             {
202             $output_file_name = "$yg-$xg.$$self{'_output_type'}";
203             $output_file_name = File::Spec -> catfile($$self{'_output_dir'}, $output_file_name) if ($$self{'_output_dir'});
204             $tile = $image -> Clone();
205              
206             Carp::croak("Error. Unable to clone image $output_file_name") if (! ref $tile);
207              
208             $result = $tile -> Crop(x => $x, y => $y, width => $$param{'tile'}{'width'}, height => $$param{'tile'}{'height'});
209              
210             Carp::croak("Error. Unable to crop image $output_file_name. Image::Magick error: $result. ") if ($result);
211              
212             if ($$self{'_return'})
213             {
214             push @{$output},
215             {
216             file_name => $output_file_name,
217             image => $tile,
218             };
219             }
220              
221             if ($$self{'_write'})
222             {
223             $tile -> Write($output_file_name);
224              
225             print "Wrote: $output_file_name. \n" if ($$self{'_verbose'});
226             }
227              
228             $y += $$param{'tile'}{'height'};
229             }
230              
231             $x += $$param{'tile'}{'width'};
232             }
233              
234             $output;
235              
236             } # End of tile.
237              
238             # -----------------------------------------------
239              
240             1;
241              
242             __END__