Changeset 15872 for gsdl/trunk/perllib/plugins/ImagePlugin.pm
- Timestamp:
- 2008-06-05T09:29:32+12:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
gsdl/trunk/perllib/plugins/ImagePlugin.pm
r15865 r15872 1 1 ########################################################################### 2 2 # 3 # ImagePlug .pm -- simple text plugin3 # ImagePlugin.pm -- simple text plugin 4 4 # A component of the Greenstone digital library software 5 5 # from the New Zealand Digital Library Project at the … … 24 24 ########################################################################### 25 25 26 package ImagePlug ;26 package ImagePlugin; 27 27 28 use BasPlug; 28 use BasePlugin; 29 use ImageConverter; 29 30 30 31 use strict; … … 32 33 33 34 sub BEGIN { 34 @ImagePlug ::ISA = ('BasPlug');35 @ImagePlugin::ISA = ('BasePlugin', 'ImageConverter'); 35 36 } 36 37 37 38 my $arguments = 38 39 [ { 'name' => "process_exp", 39 'desc' => "{Bas Plug.process_exp}",40 'desc' => "{BasePlugin.process_exp}", 40 41 'type' => "regexp", 41 42 'deft' => &get_default_process_exp(), 42 43 'reqd' => "no" }, 43 { 'name' => "cache_generated_images", 44 'desc' => "{ImagePlug.cache_generated_image}", 45 'type' => "flag", 46 'reqd' => "no" }, 47 { 'name' => "noscaleup", 48 'desc' => "{ImagePlug.noscaleup}", 49 'type' => "flag", 50 'reqd' => "no" }, 51 { 'name' => "nothumbnail", 52 'desc' => "{ImagePlug.generatethumbnail}", 53 'type' => "flag", 54 'reqd' => "no" }, 55 { 'name' => "thumbnailsize", 56 'desc' => "{ImagePlug.thumbnailsize}", 57 'type' => "int", 58 'deft' => "100", 59 'range' => "1,", 60 'reqd' => "no" }, 61 { 'name' => "thumbnailtype", 62 'desc' => "{ImagePlug.thumbnailtype}", 63 'type' => "string", 64 'deft' => "gif", 65 'reqd' => "no" }, 66 { 'name' => "noscreenview", 67 'desc' => "{ImagePlug.generatescreenview}", 68 'type' => "flag", 69 'reqd' => "no" }, 70 { 'name' => "screenviewsize", 71 'desc' => "{ImagePlug.screenviewsize}", 72 'type' => "int", 73 'deft' => "0", 74 'range' => "1,", 75 'reqd' => "no" }, 76 { 'name' => "screenviewtype", 77 'desc' => "{ImagePlug.screenviewtype}", 78 'type' => "string", 79 'deft' => "jpg", 80 'reqd' => "no" }, 81 { 'name' => "converttotype", 82 'desc' => "{ImagePlug.converttotype}", 83 'type' => "string", 84 'deft' => "", 85 'reqd' => "no" }, 86 { 'name' => "minimumsize", 87 'desc' => "{ImagePlug.minimumsize}", 88 'type' => "int", 89 'deft' => "100", 90 'range' => "1,", 91 'reqd' => "no" } ]; 44 ]; 92 45 93 my $options = { 'name' => "ImagePlug ",94 'desc' => "{ImagePlug .desc}",46 my $options = { 'name' => "ImagePlugin", 47 'desc' => "{ImagePlugin.desc}", 95 48 'abstract' => "no", 96 49 'inherits' => "yes", … … 104 57 push(@$pluginlist, $class); 105 58 106 if(defined $arguments){ push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});}107 if(defined $options) { push(@{$hashArgOptLists->{"OptList"}},$options)};59 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments}); 60 push(@{$hashArgOptLists->{"OptList"}},$options); 108 61 109 my $self = new BasPlug($pluginlist, $inputargs, $hashArgOptLists);110 $self->{'tmp_file_paths'} = ();62 new ImageConverter($pluginlist, $inputargs, $hashArgOptLists); 63 my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists); 111 64 112 # Check that ImageMagick is installed and available on the path (except for Windows 95/98) 113 if (!($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT())) { 114 my $result = `identify 2>&1`; 115 if ($? == -1 || $? == 256) { # Linux and Windows return different values for "program not found" 116 $self->{'imagemagick_not_installed'} = 1; 117 } 118 } 65 return bless $self, $class; 66 } 119 67 120 121 return bless $self, $class; 68 sub init { 69 my $self = shift (@_); 70 my ($verbosity, $outhandle, $failhandle) = @_; 71 72 $self->SUPER::init(@_); 73 $self->ImageConverter::init(); 122 74 } 123 75 … … 136 88 return; 137 89 } 138 # Create the thumbnail and screenview images, and discover the Image's139 # size, width, and height using the convert utility.140 141 sub generate_images142 {143 my $self = shift (@_);144 my $filename = shift (@_); # filename with full path145 my $file = shift (@_); # filename without path146 my $doc_obj = shift (@_);147 my $section = $doc_obj->get_top_section();148 149 my $verbosity = $self->{'verbosity'};150 my $outhandle = $self->{'outhandle'};151 152 # check the filename is okay153 return 0 if ($file eq "" || $filename eq "");154 155 # Code now extended to quote filenames in 'convert' commnads156 # Allows spaces in filenames, but note needs spaces to be escaped in URL as well157 # if ($filename =~ m/ /) {158 # print $outhandle "ImagePlug: \"$filename\" contains a space. choking.\n";159 # return undef;160 # }161 162 my $minimumsize = $self->{'minimumsize'};163 if (defined $minimumsize && (-s $filename < $minimumsize)) {164 print $outhandle "ImagePlug: \"$filename\" too small, skipping\n"165 if ($verbosity > 1);166 }167 168 169 # Convert the image to a new type (if required).170 my $converttotype = $self->{'converttotype'};171 my $originalfilename = ""; # only set if we do a conversion172 my $type = "unknown";173 174 if ($converttotype ne "" && $filename !~ m/$converttotype$/) {175 $originalfilename = $filename;176 177 my $result = $self->convert($originalfilename, $converttotype, "", "");178 ($filename) = ($result =~ /=>(.*\.$converttotype)/);179 180 $type = $converttotype;181 $file =~ s/\..*$/\.$type/;182 }183 184 185 # Add the image metadata186 my $url = $file;187 188 ##not know why it is required at the first place, it seems all works fine without it, so I comment it out189 ##$url =~ s/ /%20/g;190 191 my $utf8_filename_meta = $self->filename_to_metadata($url);192 $doc_obj->add_utf8_metadata ($section, "Image", $utf8_filename_meta);193 194 # Also want to set filename as 'Source' metadata to be195 # consistent with other plugins196 $doc_obj->add_utf8_metadata ($section, "Source", $utf8_filename_meta);197 198 my ($image_type, $image_width, $image_height, $image_size)199 = &identify($filename, $outhandle, $verbosity);200 201 if ($image_type ne " ") {202 $type = $image_type;203 }204 205 $doc_obj->add_metadata ($section, "FileFormat", $type);206 $doc_obj->add_metadata ($section, "FileSize", $image_size);207 208 $doc_obj->add_metadata ($section, "ImageType", $image_type);209 $doc_obj->add_metadata ($section, "ImageWidth", $image_width);210 $doc_obj->add_metadata ($section, "ImageHeight", $image_height);211 $doc_obj->add_metadata ($section, "ImageSize", $image_size);212 $doc_obj->add_metadata ($section, "NoText", "1");213 214 $doc_obj->add_metadata ($section, "srclink",215 "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[Image]\">");216 $doc_obj->add_metadata ($section, "/srclink", "</a>");217 218 $doc_obj->add_metadata ($section, "srcicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[Image]\" width=100>");219 220 221 # Add the image as an associated file222 $doc_obj->associate_file($filename,$file,"image/$type",$section);223 224 225 if (!$self->{'nothumbnail'}) {226 227 # Make the thumbnail image228 my $thumbnailsize = $self->{'thumbnailsize'} || 100;229 my $thumbnailtype = $self->{'thumbnailtype'} || 'gif';230 231 # Generate the thumbnail with convert232 my $result = $self->convert($filename, $thumbnailtype, "-geometry $thumbnailsize" . "x$thumbnailsize", "THUMB");233 my ($thumbnailfile) = ($result =~ /=>(.*\.$thumbnailtype)/);234 235 # Add the thumbnail as an associated file ...236 if (-e "$thumbnailfile") {237 $doc_obj->associate_file("$thumbnailfile", "thumbnail.$thumbnailtype",238 "image/$thumbnailtype",$section);239 $doc_obj->add_metadata ($section, "ThumbType", $thumbnailtype);240 $doc_obj->add_metadata ($section, "Thumb", "thumbnail.$thumbnailtype");241 242 $doc_obj->add_metadata ($section, "thumbicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[Thumb]\" width=[ThumbWidth] height=[ThumbHeight]>");243 }244 245 # Extract Thumnail metadata from convert output246 if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {247 $doc_obj->add_metadata ($section, "ThumbWidth", $1);248 $doc_obj->add_metadata ($section, "ThumbHeight", $2);249 }250 251 }252 253 254 # Make a screen-sized version of the picture if requested255 if (!$self->{'noscreenview'}) {256 257 # To do: if the actual image smaller than the screenview size,258 # we should use the original !259 260 my $screenviewsize = $self->{'screenviewsize'};261 my $screenviewtype = $self->{'screenviewtype'} || 'jpeg';262 263 # make the screenview image264 my $result = $self->convert($filename, $screenviewtype, "-geometry $screenviewsize" . "x$screenviewsize", "SCREEN");265 my ($screenviewfilename) = ($result =~ /=>(.*\.$screenviewtype)/);266 267 # get screenview dimensions, size and type268 if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {269 $doc_obj->add_metadata ($section, "ScreenWidth", $1);270 $doc_obj->add_metadata ($section, "ScreenHeight", $2);271 }272 else {273 $doc_obj->add_metadata ($section, "ScreenWidth", $image_width);274 $doc_obj->add_metadata ($section, "ScreenHeight", $image_height);275 }276 277 #add the screenview as an associated file ...278 if (-e "$screenviewfilename") {279 $doc_obj->associate_file("$screenviewfilename", "screenview.$screenviewtype",280 "image/$screenviewtype",$section);281 $doc_obj->add_metadata ($section, "ScreenType", $screenviewtype);282 $doc_obj->add_metadata ($section, "Screen", "screenview.$screenviewtype");283 284 $doc_obj->add_metadata ($section, "screenicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[Screen]\" width=[ScreenWidth] height=[ScreenHeight]>");285 } else {286 print $outhandle "ImagePlug: couldn't find \"$screenviewfilename\"\n";287 }288 }289 290 return $type;291 292 293 }294 295 296 297 # Discover the characteristics of an image file with the ImageMagick298 # "identify" command.299 300 sub identify {301 my ($image, $outhandle, $verbosity) = @_;302 303 # Use the ImageMagick "identify" command to get the file specs304 my $command = "identify \"$image\" 2>&1";305 print $outhandle "$command\n" if ($verbosity > 2);306 my $result = '';307 $result = `$command`;308 print $outhandle "$result\n" if ($verbosity > 3);309 310 # Read the type, width, and height311 my $type = 'unknown';312 my $width = 'unknown';313 my $height = 'unknown';314 315 my $image_safe = quotemeta $image;316 if ($result =~ /^$image_safe (\w+) (\d+)x(\d+)/) {317 $type = $1;318 $width = $2;319 $height = $3;320 }321 322 # Read the size323 my $size = "unknown";324 if ($result =~ m/^.* ([0-9]+)b/) {325 $size = $1;326 }327 elsif ($result =~ m/^.* ([0-9]+)(\.([0-9]+))?kb?/) {328 $size = 1024 * $1;329 if (defined($2)) {330 $size = $size + (1024 * $2);331 # Truncate size (it isn't going to be very accurate anyway)332 $size = int($size);333 }334 }335 elsif ($result =~ m/^.* (([0-9]+)(\.([0-9]+))?e\+([0-9]+))(kb|b)?/) {336 # Deals with file sizes on Linux of type "3.4e+02kb" where e+02 is 1*10^2.337 # 3.4e+02 therefore evaluates to 3.4 x 1 x 10^2 = 340kb.338 # Programming languages including Perl know how that 3.4e+02 is a number,339 # so we don't need to do any calculations.340 $size = $1*1; # turn the string into a number by multiplying it by 1341 #if we did $size = $1; $size would be merely the string "3.4e+02"342 $size = int($size); # truncate size343 }344 print $outhandle "file: $image:\t $type, $width, $height, $size\n"345 if ($verbosity > 2);346 347 # Return the specs348 return ($type, $width, $height, $size);349 }350 351 352 sub convert353 {354 my $self = shift(@_);355 my $source_file_path = shift(@_);356 my $target_file_type = shift(@_);357 my $convert_options = shift(@_) || "";358 my $convert_type = shift(@_) || "";359 360 my $outhandle = $self->{'outhandle'};361 my $verbosity = $self->{'verbosity'};362 363 # Determine the full name and path of the output file364 my $target_file_path = &util::get_tmp_filename() . "." . $target_file_type;365 push(@{$self->{'tmp_file_paths'}}, $target_file_path);366 367 # Generate and run the convert command368 my $convert_command = "convert -interlace plane -verbose $convert_options \"$source_file_path\" \"$target_file_path\"";369 print $outhandle "$convert_type $convert_command\n" if ($verbosity > 2);370 my $result = `$convert_command 2>&1`;371 print $outhandle "$convert_type RESULT = $result\n" if ($verbosity > 2);372 373 return $result;374 }375 376 377 # The ImagePlug read() function.378 # ImagePlug overrides read() because there is no need to read the actual379 # text of the file in, because the contents of the file is not text...380 #381 # Return number of files processed, undef if can't process382 # Note that $base_dir might be "" and that $file might383 # include directories384 385 sub read {386 my $self = shift (@_);387 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;388 389 my $outhandle = $self->{'outhandle'};390 391 #check process and block exps, smart block, etc392 my ($block_status,$filename) = $self->read_block(@_);393 return $block_status if ((!defined $block_status) || ($block_status==0));394 395 print STDERR "<Processing n='$file' p='ImagePlug'>\n" if ($gli);396 print $outhandle "ImagePlug processing $file\n"397 if $self->{'verbosity'} > 1;398 399 # None of this works very well on Windows 95/98...400 if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {401 if ($gli) {402 print STDERR "<ProcessingError n='$file' r='Windows 95/98 not supported'>\n";403 }404 print $outhandle "ImagePlug: Windows 95/98 not supported\n";405 return -1;406 }407 408 # None of this is going to work very well without ImageMagick...409 if ($self->{'imagemagick_not_installed'}) {410 if ($gli) {411 print STDERR "<ProcessingError n='$file' r='ImageMagick not installed'>\n";412 }413 print $outhandle "ImagePlug: ImageMagick not installed\n";414 return -1;415 }416 417 #if there's a leading directory name, eat it...418 $file =~ s/^.*[\/\\]//;419 420 # create a new document421 my $doc_obj = new doc ($filename, "indexed_doc");422 $doc_obj->set_OIDtype ($processor->{'OIDtype'}, $processor->{'OIDmetadata'});423 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");424 425 #run convert to get the thumbnail and extract size and type info426 my $result = generate_images($self, $filename, $file, $doc_obj);427 428 if (!defined $result)429 {430 if ($gli) {431 print STDERR "<ProcessingError n='$file'>\n";432 }433 print $outhandle "ImagePlug: couldn't process \"$filename\"\n";434 return -1; # error during processing435 }436 437 438 #create an empty text string so we don't break downstream plugins439 my $text = &gsprintf::lookup_string("{BasPlug.dummy_text}",1);440 441 # include any metadata passed in from previous plugins442 # note that this metadata is associated with the top level section443 my $section = $doc_obj->get_top_section();444 $self->extra_metadata ($doc_obj, $section, $metadata);445 446 # do plugin specific processing of doc_obj447 unless (defined ($self->process(\$text, $pluginfo, $base_dir, $file, $metadata, $doc_obj))) {448 print STDERR "<ProcessingError n='$file'>\n" if ($gli);449 return -1;450 }451 452 # do any automatic metadata extraction453 $self->auto_extract_metadata ($doc_obj);454 455 # if we haven't found any Title so far, assign one456 # this was shifted to here from inside read()457 $self->title_fallback($doc_obj,$section,$file);458 # add an OID459 $doc_obj->set_OID();460 $doc_obj->add_utf8_text($section, $text);461 462 # process the document463 $processor->process($doc_obj);464 465 # clean up temporary files - we do this here instead of in466 # generate_images becuase associated files aren't actually copied467 # until after process has been run.468 foreach my $tmp_file_path (@{$self->{'tmp_file_paths'}})469 {470 if (-e $tmp_file_path)471 {472 &util::rm($tmp_file_path);473 }474 }475 476 $self->{'num_processed'}++;477 478 return 1;479 }480 90 481 91 # do plugin specific processing of doc_obj 482 92 sub process { 483 93 my $self = shift (@_); 484 my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_; 94 # options?? 95 my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_; 96 485 97 my $outhandle = $self->{'outhandle'}; 98 my ($filename_full_path, $filename_no_path) = $self->get_full_filenames($base_dir, $file); 99 if ($self->check_image_magick()) { 100 $self->generate_images($filename_full_path, $filename_no_path, $doc_obj, $doc_obj->get_top_section()); # should we check the return value? 101 } else { 102 # do some basic stuff 103 # associate the image, fileformat, mimetype, srclink, srcicon 104 # do this if image magick not installed. but also if generate hasn't worked?? what about images too small? 105 } 106 #we have no text - adds dummy text and NoText metadata 107 $self->add_dummy_text($doc_obj, $doc_obj->get_top_section()); 108 109 return 1; 110 111 } 112 113 sub clean_up_after_doc_obj_processing { 114 my $self = shift(@_); 486 115 487 return 1;116 $self->ImageConverter::clean_up_temporary_files(); 488 117 } 489 118
Note:
See TracChangeset
for help on using the changeset viewer.