File Coverage

blib/lib/Imager/Album.pm
Criterion Covered Total %
statement 15 196 7.6
branch 0 42 0.0
condition 0 3 0.0
subroutine 5 23 21.7
pod 0 13 0.0
total 20 277 7.2


line stmt bran cond sub pod time code
1             package Imager::Album;
2              
3 1     1   1098 use strict;
  1         1  
  1         52  
4 1     1   1200 use Storable (); # Avoid imports
  1         7356  
  1         29  
5              
6 1     1   10 use File::Basename;
  1         7  
  1         130  
7 1     1   6 use File::Spec;
  1         2  
  1         25  
8              
9 1     1   5 use vars qw($VERSION @suf);
  1         1  
  1         5390  
10              
11             @suf = qw( jpeg jpg tiff tif gif png ppm pgm pbm png );
12              
13              
14             $VERSION = '0.06';
15              
16             #
17             # Methods
18             #
19              
20              
21             sub new {
22 0     0 0   my $class = shift;
23 0           my %opts = @_;
24 0           my $self = {};
25 0           bless $self,$class;
26 0           $self->{'preview_opts'} = {xpixels => 100, qtype=>'preview'};
27             $self->{'commands'} = [ ['Rotate cw', \&rotate_image_cw],
28             ['Rotate ccw', \&rotate_image_ccw],
29 0     0     ['Export', sub { shift; $self->{'gui'}->export_gallery(@_); } ],
  0            
30 0     0     ['Captions', sub { shift; $self->{'gui'}->label(@_); } ],
  0            
31 0     0     ['Store', sub { shift; $self->store(); }],
  0            
32 0     0     ['Remove', sub { shift; $self->{'gui'}->remove_images(@_); }],
  0            
33 0     0     ['Quit', sub { shift; $self->{'gui'}->shutdown(); }],
  0            
  0            
34             ];
35              
36              
37              
38 0 0         my $dir = exists $opts{'working_dir'} ? $opts{'working_dir'} : undef;
39 0           $self->set_working_dir($dir);
40              
41 0           $self->{'seq'} = 1;
42 0 0         if (-f $self->{'dir'}."/store") {
43 0           $self->{'images'} = Storable::retrieve($self->{'dir'}."/store");
44 0           $self->{'ordering'} = Storable::retrieve($self->{'dir'}."/ordering");
45             # $self->{'ordering'} = [keys %{$self->{images}}];
46 0           print "@{$self->{ordering}}\n";
  0            
47 0           for (keys %{$self->{'images'}}) {
  0            
48 0 0         $self->{'seq'}=$_+1 if $_ >= $self->{'seq'};
49             }
50             } else {
51 0           $self->{'images'} = {};
52 0           $self->{'orering'} = [];
53             }
54 0           return $self;
55             }
56              
57              
58              
59              
60             sub store {
61 0     0 0   my $self = shift;
62 0           my %imcopy = %{$self->{'images'}};
  0            
63 0           for (keys %imcopy) {
64 0           delete $imcopy{$_}->{'gdk_preview'};
65             }
66              
67 0           Storable::nstore(\%imcopy, $self->{'dir'}."/store");
68 0           Storable::nstore($self->{'ordering'}, $self->{'dir'}."/ordering");
69 0           print "stored current status in directory: ".$self->{'dir'}."\n";
70             }
71              
72              
73              
74              
75              
76             sub set_working_dir {
77 0     0 0   my $self = shift;
78 0   0       my $base = shift || $ENV{HOME}."/.Imager__Album_$$";
79 0 0         if (!-d $base) {
80 0 0         mkdir($base,0777)
81             or die "Couldn't create working dir '$base': $!\n";
82             }
83 0 0         if (!-d "$base/preview") {
84 0 0         mkdir("$base/preview",0777)
85             or die "Couldn't create working dir '$base/preview': $!\n";
86             }
87 0           $self->{'dir'} = $base;
88             }
89              
90              
91              
92              
93             sub add_image {
94 0     0 0   my $self = shift;
95 0           my $fname = shift;
96 0           my $num = $self->{'seq'}++;
97              
98 0           my ($name, $path, $suffix) = fileparse($fname, @suf);
99 0           my %hash;
100              
101 0 0         return undef unless -f $fname;
102              
103 0           $hash{path} = $fname;
104 0           $hash{name} = $name;
105 0           $hash{caption} = $name;
106 0           $hash{rotated} = 0;
107 0           $hash{valid} = 0;
108              
109              
110 0           push(@{$self->{'ordering'}}, $num);
  0            
111 0           $self->{'images'}->{$num} = \%hash;
112             }
113              
114              
115             sub get_image {
116 0     0 0   my ($self, $imageno) = @_;
117 0           return $self->{'images'}->{$imageno};
118             }
119              
120              
121             sub get_preview_path {
122 0     0 0   my ($self, $imageno) = @_;
123 0           my $path = File::Spec->catfile($self->{'dir'},
124             'preview',
125             $imageno.".png");
126 0           return $path;
127             }
128              
129              
130              
131             # Find which images need to have previews
132             # updated and call update_preview on those.
133              
134             sub update_previews {
135 0     0 0   my $self = shift;
136 0           my %images = %{$self->{'images'}};
  0            
137 0           my @process = grep { !$images{$_}->{valid} } keys %images;
  0            
138 0           my $imageno;
139 0           my $c = 1;
140 0           for $imageno (@process) {
141 0           print "Updating preview $c/".@process."\n";
142 0           $c++;
143 0           $self->update_preview($imageno);
144             }
145             }
146              
147              
148              
149             # Update an images preview file
150              
151             sub update_preview {
152 0     0 0   my $self = shift;
153 0           my $imageno = shift;
154 0           my %opts = %{$self->{'preview_opts'}};
  0            
155              
156 0           my $image = $self->{'images'}->{$imageno};
157 0           my $file = $image->{'path'};
158 0           my $img = Imager->new();
159              
160 0 0         if (!$img->read(file=>$file)) {
161 0           print "ERROR $file: ".$img->errstr;
162 0           return ();
163             }
164              
165 0           my $prev = $img->scale(%opts);
166 0 0         if ($image->{'rotated'}) {
167 0           $prev = $prev->rotate(degrees=>$image->{'rotated'}*90);
168             }
169 0           my $dir = $self->{'dir'};
170 0 0         $prev->write(file=>"$dir/preview/$imageno.png") or die $!;
171 0           $image->{'valid'} = 1;
172             }
173              
174              
175              
176             sub rotate_image_cw {
177 0     0 0   my ($self, @imagenos) = @_;
178 0           my @images = map { $self->{'images'}->{$_} } @imagenos;
  0            
179              
180 0           for (@images) {
181 0           $_->{'rotated'}++;
182 0           $_->{'valid'} = 0;
183             }
184             }
185              
186              
187             sub rotate_image_ccw {
188 0     0 0   my ($self, @imagenos) = @_;
189 0           my @images = map { $self->{'images'}->{$_} } @imagenos;
  0            
190              
191 0           for (@images) {
192 0           $_->{'rotated'}--;
193 0           $_->{'valid'} = 0;
194             }
195             }
196              
197              
198             sub change_order {
199 0     0 0   my ($self, $from, $to) = @_;
200 0           my $aref = $self->{'ordering'};
201 0           my $tmp = splice(@{$aref}, $from, 1);
  0            
202 0           splice(@{$aref}, $to, 0, $tmp);
  0            
203             }
204              
205              
206             # Give ids
207             sub remove_images {
208 0     0 0   my ($self, @imagenos) = @_;
209 0           delete $self->{'images'}->{$_} for @imagenos;
210              
211 0           my $imageno;
212 0           for $imageno (@imagenos) {
213 0           my @order = @{$self->{'ordering'}};
  0            
214 0           for (0..@order-1) {
215 0 0         if ($imageno == $order[$_]) {
216 0           splice(@{$self->{'ordering'}}, $_, 1);
  0            
217             }
218             }
219 0           @order = @{$self->{'ordering'}};
  0            
220             }
221             }
222              
223              
224              
225              
226              
227              
228              
229              
230              
231              
232              
233              
234              
235              
236              
237              
238              
239              
240              
241              
242              
243             sub export {
244 0     0 0   my ($self, $destdir, $albumname) = @_;
245 0           my @images = @{$self->{'ordering'}};
  0            
246              
247 0           print "Exporting images: @images\n";
248              
249 0           my %opts1 = (xpixels => 688, ypixels => 688, type=>'min');
250 0           my %opts2 = (xpixels => 200, ypixels => 200, type=>'min');
251              
252 0 0         mkdir($destdir, 0777) or die "$!\n";
253              
254 0           my $imageno;
255 0           my $cnt = 0;
256              
257 0           for $imageno (@images) {
258 0           print "Processing image $cnt/".@images."\n";
259 0           $cnt++;
260 0           my $ihash = $self->{'images'}->{$imageno};
261 0           my $img = Imager->new();
262 0 0         $img->read(file=>$ihash->{'path'}) or die $img->errstr;
263              
264 0           my %sopts1 = %opts1;
265 0           my %sopts2 = %opts2;
266              
267 0 0         if ($ihash->{'rotated'} % 2) {
268 0           my $t = $sopts1{'xpixels'};
269 0           $sopts1{'xpixels'} = $sopts1{'ypixels'};
270 0           $sopts1{'ypixels'} = $t;
271              
272 0           $t = $sopts2{'xpixels'};
273 0           $sopts2{'xpixels'} = $sopts2{'ypixels'};
274 0           $sopts2{'ypixels'} = $t;
275              
276             }
277              
278 0           $img = $img->scale(%sopts1);
279              
280 0 0         if ($ihash->{'rotated'}) {
281 0           $img = $img->rotate(degrees=>$ihash->{'rotated'}*90);
282             }
283              
284 0 0         $img->write(file=>"$destdir/$imageno.jpg") or die $img->errstr;
285 0           $img = $img->scale(%sopts2);
286 0 0         $img->write(file=>"$destdir/${imageno}_h.jpg") or die $img->errstr;
287             }
288              
289 0           local *FHIDX;
290 0 0         open(FHIDX, ">$destdir/index.html") or die "Cannot open >$destdir/index.html : $!\n";
291              
292 0           print FHIDX "$albumname\n";
293 0           print FHIDX "
\n";
294 0           print FHIDX "\n";
295 0           print FHIDX "$albumname\n";
296 0           print FHIDX "\n"; " if !($c++%3); \n"; \n";
297 0           my $c = 0;
298 0           for $imageno (@images) {
299 0           my $ihash = $self->{'images'}->{$imageno};
300 0           my $name = $ihash->{'name'};
301 0           my $caption = $ihash->{'caption'};
302              
303 0 0         print FHIDX "
304              
305              
306 0           print FHIDX "

\n";
307 0           print FHIDX "$name
308              
309              
310 0           local *FH;
311 0 0         open(FH, ">$destdir/${imageno}.html") or die $!;
312 0           print FH "$albumname\n";
313 0           print FH "
\n";
314 0           print FH "\n";
315 0           print FH "
\n";
316 0           print FH "

\n";

317 0           print FH "$name
\n";
318 0           print FH "$caption\n";
319 0           print FH "
\n";
320 0           print FH "\n";
321             }
322              
323 0           print FHIDX "
324 0           print FHIDX "
\n";
325 0           print FHIDX "\n";
326 0           close(FHIDX);
327             }
328              
329              
330              
331              
332             1;
333             __END__