source: main/trunk/greenstone2/perllib/plugins/ImageConverter.pm@ 31926

Last change on this file since 31926 was 31926, checked in by kjdon, 7 years ago

added a new option 'store_original_image'. If this is set, and the original image was converted to a new type, then we will also store the original. This was added for pei jones. Have tif images, want png source, thumb and screen images, but also want the tif files for doc editing purposes. have done no work on this if there are funny characters in the filename or different encodings

  • Property svn:executable set to *
File size: 24.5 KB
RevLine 
[16025]1###########################################################################
2#
3# ImageConverter - helper plugin that does image conversion using ImageMagick
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright (C) 2008 New Zealand Digital Library Project
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
[15866]26package ImageConverter;
27
[16981]28use BaseMediaConverter;
[15866]29
[16825]30
[15866]31use strict;
[16382]32no strict 'refs'; # allow filehandles to be variables and viceversa
33
[24600]34use util;
[27519]35use FileUtils;
[16008]36use gsprintf 'gsprintf';
[15866]37
38BEGIN {
[16981]39 @ImageConverter::ISA = ('BaseMediaConverter');
[15866]40}
41
[24346]42# When used with multiple builder+buildproc, plugins loaded multiple times
43# => use this 'our' var to ensure only see the warning about ImageMagick once
44our $given_image_conversion_warning = 0;
45
[15866]46my $arguments = [
47 { 'name' => "create_thumbnail",
[16008]48 'desc' => "{ImageConverter.create_thumbnail}",
49 'type' => "enum",
[16016]50 'list' => [{'name' => "true", 'desc' => "{common.true}"},
51 {'name' => "false", 'desc' => "{common.false}"}],
[15866]52 'deft' => "true",
53 'reqd' => "no" },
54 { 'name' => "thumbnailsize",
55 'desc' => "{ImageConverter.thumbnailsize}",
56 'type' => "int",
57 'deft' => "100",
58 'range' => "1,",
59 'reqd' => "no" },
60 { 'name' => "thumbnailtype",
61 'desc' => "{ImageConverter.thumbnailtype}",
62 'type' => "string",
63 'deft' => "gif",
64 'reqd' => "no" },
[16008]65 { 'name' => "noscaleup",
66 'desc' => "{ImageConverter.noscaleup}",
67 'type' => "flag",
68 'reqd' => "no" },
[15866]69 { 'name' => "create_screenview",
[16008]70 'desc' => "{ImageConverter.create_screenview}",
71 'type' => "enum",
[16016]72 'list' => [{'name' => "true", 'desc' => "{common.true}"},
73 {'name' => "false", 'desc' => "{common.false}"}],
[15866]74 'deft' => "true",
75 'reqd' => "no" },
76 { 'name' => "screenviewsize",
77 'desc' => "{ImageConverter.screenviewsize}",
78 'type' => "int",
79 'deft' => "500",
80 'range' => "1,",
81 'reqd' => "no" },
82 { 'name' => "screenviewtype",
83 'desc' => "{ImageConverter.screenviewtype}",
84 'type' => "string",
85 'deft' => "jpg",
86 'reqd' => "no" },
87 { 'name' => "converttotype",
88 'desc' => "{ImageConverter.converttotype}",
89 'type' => "string",
90 'deft' => "",
91 'reqd' => "no" },
92 { 'name' => "minimumsize",
93 'desc' => "{ImageConverter.minimumsize}",
94 'type' => "int",
95 'deft' => "100",
96 'range' => "1,",
[26866]97 'reqd' => "no" },
[31926]98 { 'name' => "store_original_image",
99 'desc' => "{ImageConverter.store_original_image}",
100 'type' => "flag",
101 'reqd' => "no"},
[26866]102 { 'name' => "apply_aspectpad",
103 'desc' => "{ImageConverter.apply_aspectpad}",
104 'type' => "enum",
105 'list' => [{'name' => "true", 'desc' => "{common.true}"},
106 {'name' => "false", 'desc' => "{common.false}"}],
107 'deft' => "false",
108 'reqd' => "no" },
109 { 'name' => "aspectpad_ratio",
110 'desc' => "{ImageConverter.aspectpad_ratio}",
111 'type' => "string",
112 'deft' => "2",
113 'range' => "1,",
114 'reqd' => "no" },
115 { 'name' => "aspectpad_mode",
116 'desc' => "{ImageConverter.aspectpad_mode}",
117 'type' => "enum",
118 'list' => [{'name' => "al", 'desc' => "{aspectpad.al}"},
119 {'name' => "ap", 'desc' => "{aspectpad.ap}"},
120 {'name' => "l", 'desc' => "{aspectpad.l}"},
121 {'name' => "p", 'desc' => "{aspectpad.p}"}],
122 'deft' => "al",
123 'reqd' => "no" },
124 { 'name' => "aspectpad_colour",
125 'desc' => "{ImageConverter.aspectpad_colour}",
126 'type' => "string",
127 'deft' => "transparent",
128 'reqd' => "no" },
129 { 'name' => "aspectpad_tolerance",
130 'desc' => "{ImageConverter.aspectpad_tolerance}",
131 'type' => "string",
132 'deft' => "0.0",
133 'range' => "0,",
134 'reqd' => "no" },
135
136
[15866]137 ];
138
139my $options = { 'name' => "ImageConverter",
140 'desc' => "{ImageConverter.desc}",
141 'abstract' => "yes",
142 'inherits' => "yes",
143 'args' => $arguments };
144
145sub new {
146 my ($class) = shift (@_);
147 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
148 push(@$pluginlist, $class);
149
150 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
151 push(@{$hashArgOptLists->{"OptList"}},$options);
152
[16981]153 my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
[15866]154
[16825]155
[15866]156 return bless $self, $class;
157
158}
159
[31492]160# needs to be called after BaseImporter init, so that outhandle is set up.
[15866]161sub init {
162 my $self = shift(@_);
163
164 $self->{'tmp_file_paths'} = ();
165
[16008]166 # Check that ImageMagick is installed and available on the path
167 my $image_conversion_available = 1;
168 my $no_image_conversion_reason = "";
[15866]169 # None of this works very well on Windows 95/98...
170 if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
[16008]171 $image_conversion_available = 0;
172 $no_image_conversion_reason = "win95notsupported";
[15866]173 } else {
[24600]174 my $imagick_cmd = "\"".&util::get_perl_exec()."\" -S gs-magick.pl";
175 my $result = `$imagick_cmd identify -help 2>&1`;
[19420]176 my $return_value = $?;
[24600]177
178 # When testing against non-zero return_value ($?), need to shift by 8
179 # and convert it to its signed value. Linux returns -1 and Windows returns
180 # 256 for "program not found". The signed equivalents are -1 and 1 respectively.
181 $return_value >>= 8;
182 $return_value = (($return_value & 0x80) ? -(0x100 - ($return_value & 0xFF)) : $return_value);
183
184 if ( ($ENV{'GSDLOS'} eq "windows" && $return_value == 1) || $return_value == -1) { # Linux and Windows return different values for "program not found"
[16008]185 $image_conversion_available = 0;
186 $no_image_conversion_reason = "imagemagicknotinstalled";
[15866]187 }
188 }
[16008]189 $self->{'image_conversion_available'} = $image_conversion_available;
190 $self->{'no_image_conversion_reason'} = $no_image_conversion_reason;
191
192 if ($self->{'image_conversion_available'} == 0) {
[24346]193 if (!$given_image_conversion_warning) {
194 my $outhandle = $self->{'outhandle'};
195 &gsprintf($outhandle, "ImageConverter: {ImageConverter.noconversionavailable} ({ImageConverter.".$self->{'no_image_conversion_reason'}."})\n");
196 $given_image_conversion_warning = 1;
197 }
[16008]198 }
[16382]199
[15866]200}
[16008]201
[15866]202
203# convert image to new type if converttotype is set
204# generate thumbnails if required
205# generate screenview if required
206# discover image metadata
[16958]207# filename_no_path must be in utf8 and url-encoded
[15866]208sub generate_images {
209 my $self = shift(@_);
[23352]210 my ($filename_full_path, $filename_encoded_full_path, $doc_obj, $section, $filename_encoding) = @_;
[15866]211
[23352]212 my ($unused_fefp,$filename_encoded_no_path)
[27354]213 = &util::get_full_filenames("",$filename_encoded_full_path);
[23352]214
215 # The following is potentially very muddled thinking (but currently seems to work)
216 # generate_images currently called from ImagePlugin and PagedImagePlugin
[31926]217 my $filename_no_path = $filename_encoded_no_path;
218 my $original_filename_full_path = $filename_full_path;
219 my $original_filename_no_path = $filename_no_path;
220 my $original_file_was_converted = 0;
221
[16008]222 # check image magick status
223 return 0 if $self->{'image_conversion_available'} == 0;
[18466]224
[15866]225 # check the filenames
226 return 0 if ($filename_no_path eq "" || !-f $filename_full_path);
227
[19054]228 if ($self->{'enable_cache'}) {
[16825]229 $self->init_cache_for_file($filename_full_path);
230 }
[21344]231 if ($self->{'store_file_paths'}) {
232 $self->{'orig_file'} = "";
233 $self->{'thumb_file'} = "";
234 $self->{'screen_file'} = "";
235 }
[15866]236 my $verbosity = $self->{'verbosity'};
237 my $outhandle = $self->{'outhandle'};
238
239 # check the size of the image against minimum size if specified
240 my $minimumsize = $self->{'minimumsize'};
[27519]241 if (defined $minimumsize && (&FileUtils::fileSize($filename_full_path) < $minimumsize)) {
[15866]242 print $outhandle "ImageConverter: \"$filename_full_path\" too small, skipping\n"
243 if ($verbosity > 1);
244 return 0; # or is there a better return value??
245 }
246
247 my $filehead = $filename_no_path;
248 $filehead =~ s/\.([^\.]*)$//; # filename with no extension
249 my $assocfilemeta = "[assocfilepath]";
250 if ($section ne $doc_obj->get_top_section()) {
251 $assocfilemeta = "[parent(Top):assocfilepath]";
252 }
253
[16901]254 # The images that will get generated may contain percent signs in their src filenames
[16771]255 # Encode those percent signs themselves so that urls to the imgs refer to them correctly
[18404]256 my $url_to_filehead = &unicode::filename_to_url($filehead);
257 my $url_to_filename_no_path = &unicode::filename_to_url($filename_no_path);
[26866]258
259 my $type = "unknown";
260
[15866]261 # Convert the image to a new type (if required).
262 my $converttotype = $self->{'converttotype'};
263
264 if ($converttotype ne "" && $filename_full_path !~ m/$converttotype$/) {
[23335]265# # $doc_obj->add_utf8_metadata($section, "Image", $utf8_filename_meta);
[19540]266 my ($result, $converted_filename_full_path)
[16825]267 = $self->convert($filename_full_path, $converttotype, "", "CONVERTTYPE");
[15866]268
269 $type = $converttotype;
[19540]270 $filename_full_path = $converted_filename_full_path;
[15866]271 $filename_no_path = "$filehead.$type";
[16771]272 $url_to_filename_no_path = "$url_to_filehead.$type";
[21344]273 if ($self->{'store_file_paths'}) {
274 $self->{'orig_file'} = $converted_filename_full_path;
275 }
[31926]276 $original_file_was_converted = 1;
[15866]277 }
278
[26866]279 # Apply aspect padding (if required).
280 my $apply_aspectpad = $self->{'apply_aspectpad'};
281
282 if ($apply_aspectpad eq "true") {
283 my $aspectpad_ratio = $self->{'aspectpad_ratio'};
284 my $aspectpad_mode = $self->{'aspectpad_mode'};
285 my $aspectpad_colour = $self->{'aspectpad_colour'};
286 my $aspectpad_tolerance = $self->{'aspectpad_tolerance'};
287
288 ($type) = ($filename_full_path =~ m/\.(.*?)$/);
289 ##$type = lc($type);
290
291 my ($result, $aspectpad_filename_full_path)
292 = $self->aspectpad($filename_full_path, $type, $aspectpad_ratio, $aspectpad_mode,
293 $aspectpad_colour, $aspectpad_tolerance, "", "ASPECTPAD");
294
295 $filename_full_path = $aspectpad_filename_full_path;
296
297 if ($self->{'store_file_paths'}) {
298 $self->{'orig_file'} = $aspectpad_filename_full_path;
299 }
[31926]300 $original_file_was_converted = 1;
301
[26866]302 }
303
[15866]304 # add Image metadata
[16771]305 $doc_obj->add_utf8_metadata($section, "Image", $url_to_filename_no_path); # url to generated image
[15866]306
[16382]307 # here we overwrite the original with the potentially converted one
[23335]308# $doc_obj->set_utf8_metadata_element($section, "Source", &unicode::url_decode($filename_no_path)); # displayname of generated image
309# $doc_obj->set_utf8_metadata_element($section, "SourceFile", $url_to_filename_no_path); # displayname of generated image
[15866]310
[23335]311# $self->set_Source_metadata($doc_obj,$url_to_filename_no_path,undef);
312
[23352]313 my $raw_filename_full_path = &unicode::url_decode($filename_encoded_full_path);
314 $self->set_Source_metadata($doc_obj,$raw_filename_full_path,
[23460]315 $filename_encoding, $section);
[23335]316
317
[15866]318 # use identify to get info about the (possibly converted) image
[25778]319 my ($image_type, $image_width, $image_height, $image_size, $size_str)
[15866]320 = &identify($filename_full_path, $outhandle, $verbosity);
321
322 if ($image_type ne " ") {
[17059]323 $type = $self->correct_mime_type($image_type);
[15866]324 }
325
[31492]326 #overwrite the ones added in BaseImporter
[15866]327 $doc_obj->set_metadata_element ($section, "FileFormat", $type);
[27519]328 my $sys_file_size = &FileUtils::fileSize($filename_full_path);
[25787]329 $doc_obj->set_metadata_element ($section, "FileSize", $sys_file_size); #$image_size);
[15866]330
331 $doc_obj->add_metadata ($section, "ImageType", $image_type);
332 $doc_obj->add_metadata ($section, "ImageWidth", $image_width);
333 $doc_obj->add_metadata ($section, "ImageHeight", $image_height);
[25778]334 $doc_obj->add_metadata ($section, "ImageSize", $size_str);
[15866]335
[19054]336 if ((defined $self->{'MaxImageWidth'})
337 && ($image_width > $self->{'MaxImageWidth'})) {
338 $self->{'MaxImageWidth'} = $image_width;
339 }
340 if ((defined $self->{'MaxImageHeight'})
341 && ($image_height > $self->{'MaxImageHeight'})) {
342 $self->{'MaxImageHeight'} = $image_height;
343 }
344
[24225]345 # srclink_file is now deprecated because of the "_" in the metadataname. Use srclinkFile
[22663]346 $doc_obj->add_metadata ($section, "srclink_file", $url_to_filename_no_path);
[24225]347 $doc_obj->add_metadata ($section, "srclinkFile", $url_to_filename_no_path);
348 $doc_obj->add_metadata ($section, "srcicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[srclinkFile]\" width=\"[ImageWidth]\" height=\"[ImageHeight]\">");
[15866]349
350 # Add the image as an associated file
351 $doc_obj->associate_file($filename_full_path, $filename_no_path, "image/$type", $section);
352
[31926]353 if ($self->{'store_original_image'} && $original_file_was_converted) {
354 # hack to guess the filetype
355 my ($orig_type) = ($original_filename_full_path =~ m/\.(.*?)$/);
356 # add the original image as an associated file
357 $doc_obj->associate_file($original_filename_full_path, $original_filename_no_path, "image/$orig_type", $section);
358 }
[15866]359 if ($self->{'create_thumbnail'} eq "true") {
[16771]360 $self->create_thumbnail($filename_full_path, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead);
[15866]361 }
362 if ($self->{'create_screenview'} eq "true") {
[18466]363 $self->create_screenview($filename_full_path, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead, $image_width, $image_height);
[15866]364 }
[21722]365
366 return 1;
[15866]367}
368
369sub create_thumbnail {
370 my $self = shift(@_);
[16771]371 my ($original_file, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead) = @_;
372 $url_to_filehead = $filehead unless defined $url_to_filehead;
[15866]373
374 my $thumbnailsize = $self->{'thumbnailsize'};
[17059]375 my $thumbnailtype = $self->correct_mime_type($self->{'thumbnailtype'});
[18466]376
[15866]377 # Generate the thumbnail with convert
[16825]378 my ($result,$thumbnailfile)
379 = $self->convert($original_file, $thumbnailtype, "-geometry $thumbnailsize" . "x$thumbnailsize", "THUMB");
[15866]380
381 # Add the thumbnail as an associated file ...
382 if (-e "$thumbnailfile") {
383 $doc_obj->associate_file("$thumbnailfile", $filehead."_thumb.$thumbnailtype",
[16771]384 "image/$thumbnailtype",$section); # name of generated image
[15866]385 $doc_obj->add_metadata ($section, "ThumbType", $thumbnailtype);
[16771]386 $doc_obj->add_utf8_metadata ($section, "Thumb", $url_to_filehead."_thumb.$thumbnailtype"); # url to generated image
[15866]387
[27787]388 $doc_obj->add_metadata ($section, "thumbicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Thumb]\" alt=\"[Thumb]\" width=\"[ThumbWidth]\" height=\"[ThumbHeight]\">");
[15866]389
390
391 # Extract Thumbnail metadata from convert output
392 if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {
393 $doc_obj->add_metadata ($section, "ThumbWidth", $1);
394 $doc_obj->add_metadata ($section, "ThumbHeight", $2);
395 }
[21344]396 if ($self->{'store_file_paths'}) {
397 $self->{'thumb_file'} = $thumbnailfile;
398 }
399
[15866]400 } else {
401 my $outhandle = $self->{'outhandle'};
402 print $outhandle "Couldn't find thumbnail $thumbnailfile\n";
403
404 }
405}
406
407sub create_screenview {
408
409 my $self = shift(@_);
[18466]410 my ($original_file, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead, $image_width, $image_height) = @_;
[16771]411 $url_to_filehead = $filehead unless defined $url_to_filehead;
[15866]412
413 my $screenviewsize = $self->{'screenviewsize'};
[17059]414 my $screenviewtype = $self->correct_mime_type($self->{'screenviewtype'});
[18466]415
416 # Scale the image, unless the original image is smaller than the screenview size and -noscaleup is set
417 my $scale_option = "-geometry $screenviewsize" . "x$screenviewsize";
418 if ($self->{'noscaleup'} && $image_width < $screenviewsize && $image_height < $screenviewsize)
419 {
420 $scale_option = "";
421 }
[15866]422
423 # make the screenview image
[16825]424 my ($result,$screenviewfilename)
[18466]425 = $self->convert($original_file, $screenviewtype, $scale_option, "SCREEN");
[15866]426
427 #add the screenview as an associated file ...
428 if (-e "$screenviewfilename") {
[16771]429 $doc_obj->associate_file("$screenviewfilename", $filehead."_screen.$screenviewtype", "image/$screenviewtype",$section); # name of generated image
[15866]430 $doc_obj->add_metadata ($section, "ScreenType", $screenviewtype);
[16771]431 $doc_obj->add_utf8_metadata ($section, "Screen", $url_to_filehead."_screen.$screenviewtype"); # url to generated image
[15866]432
433 $doc_obj->add_metadata ($section, "screenicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Screen]\" width=[ScreenWidth] height=[ScreenHeight]>");
434
435 # get screenview dimensions, size and type
436 if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {
437 $doc_obj->add_metadata ($section, "ScreenWidth", $1);
438 $doc_obj->add_metadata ($section, "ScreenHeight", $2);
439 } elsif ($result =~ m/([0-9]+)x([0-9]+)/) {
440 #if the image hasn't changed size, the previous regex doesn't match
441 $doc_obj->add_metadata ($section, "ScreenWidth", $1);
442 $doc_obj->add_metadata ($section, "ScreenHeight", $2);
443 }
[21344]444
445 if ($self->{'store_file_paths'}) {
446 $self->{'screen_file'} = $screenviewfilename;
447 }
448
[15866]449 } else {
450 my $outhandle = $self->{'outhandle'};
451 print $outhandle "Couldn't find screenview file $screenviewfilename\n";
452
453 }
454
455}
456
457
458
459sub convert {
460 my $self = shift(@_);
461 my $source_file_path = shift(@_);
462 my $target_file_type = shift(@_);
[16825]463 my $convert_options = shift(@_) || "";
464 my $convert_id = shift(@_) || "";
[20540]465 my $cache_mode = shift(@_) || "";
[15866]466
467 my $outhandle = $self->{'outhandle'};
468 my $verbosity = $self->{'verbosity'};
469
[16825]470 my $source_file_no_path = &File::Basename::basename($source_file_path);
471
[15866]472 # Determine the full name and path of the output file
[16825]473 my $target_file_path;
[19054]474 if ($self->{'enable_cache'}) {
[16825]475 my $cached_image_dir = $self->{'cached_dir'};
476 my $image_root = $self->{'cached_file_root'};
477 $image_root .= "_$convert_id" if ($convert_id ne "");
478 my $image_file = "$image_root.$target_file_type";
[27354]479 $target_file_path = &FileUtils::filenameConcatenate($cached_image_dir,$image_file);
[16825]480 }
481 else {
482 $target_file_path = &util::get_tmp_filename($target_file_type);
483 push(@{$self->{'tmp_file_paths'}}, $target_file_path);
[15866]484
[16825]485 # Output filename used to be parsed from result line:
486 # my ($ofilename) = ($result =~ m/=>(.*\.$target_file_type)/);
487 # by the function that called 'convert'
488 # but this is no longer needed, as output filename is now
489 # explicitly passed back
490 }
491
[15866]492 # Generate and run the convert command
[24763]493 my $convert_command = "\"".&util::get_perl_exec()."\" -S gs-magick.pl --verbosity=".$self->{'verbosity'}." convert -interlace plane -verbose $convert_options \"$source_file_path\" \"$target_file_path\"";
[15866]494
[16825]495 my $print_info = { 'message_prefix' => $convert_id,
496 'message' => "Converting image $source_file_no_path to: $convert_id $target_file_type" };
[20540]497 $print_info->{'cache_mode'} = $cache_mode if ($cache_mode ne "");
498
[16825]499 my ($regenerated,$result,$had_error)
[22450]500 = $self->autorun_general_cmd($convert_command,$source_file_path,$target_file_path,$print_info);
[16825]501
502 return ($result,$target_file_path);
[15866]503}
504
[26866]505
[20540]506sub convert_without_result {
507 my $self = shift(@_);
[15866]508
[20540]509 my $source_file_path = shift(@_);
510 my $target_file_type = shift(@_);
511 my $convert_options = shift(@_) || "";
512 my $convert_id = shift(@_) || "";
513
514 return $self->convert($source_file_path,$target_file_type,
515 $convert_options,$convert_id,"without_result");
516}
517
518
[26866]519sub aspectpad {
520 my $self = shift(@_);
521 my $source_file_path = shift(@_);
522 my $target_file_type = shift(@_);
523 my $aspectpad_ratio = shift(@_);
524 my $aspectpad_mode = shift(@_);
525 my $aspectpad_colour = shift(@_);
526 my $aspectpad_tolerance = shift(@_);
527
528 my $aspectpad_options = shift(@_) || "";
529 my $aspectpad_id = shift(@_) || "";
530 my $cache_mode = shift(@_) || "";
531
532 my $outhandle = $self->{'outhandle'};
533 my $verbosity = $self->{'verbosity'};
534
535 my $source_file_no_path = &File::Basename::basename($source_file_path);
536
537 # Determine the full name and path of the output file
538 my $target_file_path;
539 if ($self->{'enable_cache'}) {
540 my $cached_image_dir = $self->{'cached_dir'};
541 my $image_root = $self->{'cached_file_root'};
542 $image_root .= "_$aspectpad_id" if ($aspectpad_id ne "");
543 my $image_file = "$image_root.$target_file_type";
[27354]544 $target_file_path = &FileUtils::filenameConcatenate($cached_image_dir,$image_file);
[26866]545 }
546 else {
547 $target_file_path = &util::get_tmp_filename($target_file_type);
548 push(@{$self->{'tmp_file_paths'}}, $target_file_path);
549 }
550
551 # Generate and run the aspectpad command
552 my $aspectpad_command = "\"".&util::get_perl_exec()."\" -S gs-magick.pl --verbosity=".$self->{'verbosity'}." aspectpad.sh -a $aspectpad_ratio -m $aspectpad_mode -p \"$aspectpad_colour\" -t $aspectpad_tolerance $aspectpad_options \"$source_file_path\" \"$target_file_path\"";
553
554 my $print_info = { 'message_prefix' => $aspectpad_id,
555 'message' => "Aspect padding image $source_file_no_path to: $aspectpad_id $target_file_type" };
556 $print_info->{'cache_mode'} = $cache_mode if ($cache_mode ne "");
557
558 my ($regenerated,$result,$had_error)
559 = $self->autorun_general_cmd($aspectpad_command,$source_file_path,$target_file_path,$print_info);
560
561 return ($result,$target_file_path);
562}
563
564
565
566
567
[15866]568# Discover the characteristics of an image file with the ImageMagick
569# "identify" command.
570
571sub identify {
572 my ($image, $outhandle, $verbosity) = @_;
573
574 # Use the ImageMagick "identify" command to get the file specs
[24600]575 my $command = "\"".&util::get_perl_exec()."\" -S gs-magick.pl identify \"$image\" 2>&1";
[15866]576 print $outhandle "$command\n" if ($verbosity > 2);
577 my $result = '';
578 $result = `$command`;
579 print $outhandle "$result\n" if ($verbosity > 3);
580
581 # Read the type, width, and height
582 my $type = 'unknown';
583 my $width = 'unknown';
584 my $height = 'unknown';
585
586 my $image_safe = quotemeta $image;
587 if ($result =~ /^$image_safe (\w+) (\d+)x(\d+)/) {
588 $type = $1;
589 $width = $2;
590 $height = $3;
591 }
592
593 # Read the size
594 my $size = "unknown";
[25778]595 my $size_str="unknown";
596
597 if ($result =~ m/^.* ([0-9]+)b/i) {
598 $size_str="$1B"; # display string
[15866]599 $size = $1;
600 }
[25778]601 elsif ($result =~ m/^.* ([0-9]+)(\.([0-9]+))?kb?/i) {
602 # display string stays about the same
603 $size_str="$1";
604 $size_str.="$2" if defined $2;
605 $size_str.="KB";
606
[15866]607 $size = 1024 * $1;
608 if (defined($2)) {
609 $size = $size + (1024 * $2);
610 # Truncate size (it isn't going to be very accurate anyway)
611 $size = int($size);
612 }
613 }
[25778]614 elsif ($result =~ m/^.* ([0-9]+)(\.([0-9]+))?mb?/i) {
615 # display string stays about the same
616 $size_str="$1";
617 $size_str.="$2" if defined $2;
618 $size_str.="MB";
619
[21866]620 $size = 1024 * 1024 * $1;
621 if (defined($2)) {
622 $size = $size + (1024 * 1024 * $2);
623 # Truncate size (it isn't going to be very accurate anyway)
624 $size = int($size);
625 }
[25778]626 }
627 elsif ($result =~ m/^.* ((([0-9]+)(\.([0-9]+))?e\+([0-9]+))(kb|b)?)/i) {
628 # display string stays the same
629 $size_str="$1";
630
[15866]631 # Deals with file sizes on Linux of type "3.4e+02kb" where e+02 is 1*10^2.
632 # 3.4e+02 therefore evaluates to 3.4 x 1 x 10^2 = 340kb.
633 # Programming languages including Perl know how that 3.4e+02 is a number,
634 # so we don't need to do any calculations.
[25778]635 # $2 is just the number without the kb/b at the end.
636 $size = $2*1; # turn the string into a number by multiplying it by 1
[15866]637 #if we did $size = $1; $size would be merely the string "3.4e+02"
638 $size = int($size); # truncate size
639 }
[25778]640 print $outhandle "file: $image:\t $type, $width, $height, $size, $size_str\n"
[15866]641 if ($verbosity > 2);
642
643 # Return the specs
[25778]644 return ($type, $width, $height, $size, $size_str);
[15866]645}
646
647sub clean_up_temporary_files {
648 my $self = shift(@_);
649
650 foreach my $tmp_file_path (@{$self->{'tmp_file_paths'}}) {
651 if (-e $tmp_file_path) {
[27354]652 &FileUtils::removeFiles($tmp_file_path);
[15866]653 }
654 }
655
656}
657
[17059]658# image/jpg is not a valid mime-type, it ought to be image/jpeg.
659# Sometimes JPEG is passed in also, want to keep things lowercase just in case.
660sub correct_mime_type {
661 my $self = shift(@_);
662 my ($file_extension) = @_;
663
664 $file_extension = lc($file_extension);
665 $file_extension =~ s/jpg/jpeg/s;
666
667 return $file_extension;
668}
669
[15866]6701;
Note: See TracBrowser for help on using the repository browser.