source: trunk/gsdl/perllib/plugins/ImagePlug.pm@ 2882

Last change on this file since 2882 was 2882, checked in by paynter, 21 years ago

Compensate for change to "convert" output (size data goes to STDERR
instead of STDOUT).

  • Property svn:keywords set to Author Date Id Revision
File size: 10.7 KB
Line 
1###########################################################################
2#
3# ImagePlug.pm -- simple text plugin
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26package ImagePlug;
27
28use BasPlug;
29
30sub BEGIN {
31 @ISA = ('BasPlug');
32}
33
34
35sub print_usage {
36 my ($plugin_name) = @_;
37
38 print STDERR "
39 usage: plugin ImagePlug [options]
40
41 -noscaleup Don't scale up small images when making thumbnails
42
43 -thumbnailsize n Make thumbnails of size nxn
44
45 -thumbnailtype s Make thumbnails in format 's'
46
47 -screenviewsize n If set, makes an image of size n for screen display
48 and sets Screen, ScreenSize, ScrrenWidth and Screeneight
49 metadata. By default it is not set.
50
51 -screenviewtype s If -screenviewsize is set, this sets the screen display
52 image type. Defaults to jpg.
53
54 -convertto s Convert main inage to (gif|png|jpg)
55
56 -minimumsize n Ignore images smaller than n bytes
57
58"
59}
60
61sub new {
62 my ($class) = @_;
63 my $plugin_name = shift (@_);
64 my $self = new BasPlug ("ImagePlug", @_);
65
66 if (!parsargv::parse(\@_,
67 q^noscaleup^, \$self->{'noscaleup'},
68 q^converttotype/.*/^, \$self->{'converttotype'},
69 q^minimumsize/[0-9]*/100^, \$self->{'minimumsize'},
70
71 q^thumbnailsize/[0-9]*/100^, \$self->{'thumbnailsize'},
72 q^thumbnailtype/.*/gif^, \$self->{'thumbnailtype'},
73 q^screenviewsize/[0-9]*/0^, \$self->{'screenviewsize'},
74 q^screenviewtype/.*/jpg^, \$self->{'screenviewtype'},
75 "allow_extra_options")) {
76
77 print STDERR "\nImagePlug uses an incorrect option.\n";
78 print STDERR "Check your collect.cfg configuration file.\n";
79 &print_usage($plugin_name);
80 die "\n";
81 }
82
83 return bless $self, $class;
84}
85
86sub get_default_process_exp {
87 my $self = shift (@_);
88
89 return q^(?i)(\.jpe?g|\.gif|\.png|\.bmp|\.xbm|\.tif?f)$^;
90}
91
92
93# Create the thumbnail and screenview images, and discover the Image's
94# size, width, and height using the convert utility.
95
96sub run_convert {
97 my $self = shift (@_);
98 my $filename = shift (@_); # filename with full path
99 my $file = shift (@_); # filename without path
100 my $doc_obj = shift (@_);
101 my $section = $doc_obj->get_top_section();
102
103 my $verbosity = $self->{'verbosity'};
104 my $outhandle = $self->{'outhandle'};
105
106 # check the filename is okay
107 return 0 if ($file eq "" || $filename eq "");
108
109 if ($filename =~ m/ /) {
110 print $outhandle "ImagePlug: \"$filename\" contains a space. choking.\n";
111 return undef;
112 }
113
114 my $minimumsize = $self->{'minimumsize'};
115 if (defined $minimumsize && (-s $filename < $minimumsize)) {
116 print $outhandle "ImagePlug: \"$filename\" too small, skipping\n"
117 if ($verbosity > 1);
118 }
119
120
121 # Convert the image to a new type (if required).
122 my $converttotype = $self->{'converttotype'};
123 my $originalfilename = ""; # only set if we do a conversion
124 my $type = "unknown";
125
126 if ($converttotype ne "" && $filename =~ m/$converttotype$/) {
127
128 $originalfilename = $filename;
129 $filename = &util::get_tmp_filename() . ".$converttotype";
130 $self->{'tmp_filename'} = $filename;
131
132 my $command = "convert -verbose $originalfilename $filename";
133 print $outhandle "$command\n" if ($verbosity > 2);
134 my $result = '';
135 $result = `$command`;
136 print $outhandle "$result\n" if ($verbosity > 3);
137
138 $type = $converttotype;
139 }
140
141
142 # Make the thumbnail image
143 my $thumbnailsize = $self->{'thumbnailsize'} || 100;
144 my $thumbnailtype = $self->{'thumbnailtype'} || 'gif';
145
146 my $thumbnailfilename = &util::get_tmp_filename() . ".$thumbnailtype";
147 $self->{'tmp_filename2'} = $thumbnailfilename;
148
149 # Generate the thumbnail with convert
150 my $command = "convert -verbose -geometry $thumbnailsize"
151 . "x$thumbnailsize $filename $thumbnailfilename";
152 print $outhandle "$command\n" if ($verbosity > 2);
153 my $result = '';
154 $result = `$command 2>&1` ;
155 print $outhandle "$result\n" if ($verbosity > 3);
156
157 # Add the thumbnail as an associated file ...
158 if (-e "$thumbnailfilename") {
159 $doc_obj->associate_file("$thumbnailfilename", "thumbnail.$thumbnailtype",
160 "image/$thumbnailtype",$section);
161 $doc_obj->add_metadata ($section, "ThumbType", $thumbnailtype);
162 $doc_obj->add_metadata ($section, "Thumb", "thumbnail.$thumbnailtype");
163 }
164
165
166 # Extract Image metadata from convert output
167 if ($result =~ m/([0-9]+)x([0-9]+)=>([0-9]+)x([0-9]+)/) {
168 $doc_obj->add_metadata ($section, "ImageWidth", $1);
169 $doc_obj->add_metadata ($section, "ImageHeight", $2);
170 $doc_obj->add_metadata ($section, "ThumbWidth", $3);
171 $doc_obj->add_metadata ($section, "ThumbHeight", $4);
172 }
173
174 my $size = "unknown";
175 if ($result =~ m/^[^\n]* ([0-9]+)b/) {
176 $size = $1;
177 } elsif ($result =~ m/^[^\n]* ([0-9]+)kb/) {
178 $size = 1024 * $1;
179 }
180
181 if ($result =~ m/^[^\n]*JPE?G/i) {
182 $type = "jpeg";
183 } elsif ($result =~ m/^[^\n]*GIF/i) {
184 $type = "gif";
185 } elsif ($result =~ m/^[^\n]*PNG/i) {
186 $type = "png";
187 } elsif ($result =~ m/^[^\n]*TIF?F/i) {
188 $type = "tiff";
189 } elsif ($result =~ m/^[^\n]*BMP/i) {
190 $type = "bmp";
191 } elsif ($result =~ m/^[^\n]*XBM?F/i) {
192 $type = "xbm";
193 }
194
195 $doc_obj->add_metadata ($section, "ImageType", $type);
196 $doc_obj->add_metadata ($section, "Image", "$file");
197 $doc_obj->add_metadata ($section, "ImageSize", $size);
198
199 # Add the image as an associated file ...
200 $doc_obj->associate_file($filename,$file,"image/$type",$section);
201
202
203 # Make a screen-sized version of the picture if requested
204 if ($self->{'screenviewsize'}) {
205
206 my $screenviewsize = $self->{'screenviewsize'};
207 my $screenviewtype = $self->{'screenviewtype'} || 'jpeg';
208 my $screenviewfilename = &util::get_tmp_filename() . ".$screenviewtype";
209 $self->{'tmp_filename3'} = $screenviewfilename;
210
211 # make the screenview image
212 my $command = "convert -verbose -geometry $screenviewsize"
213 . "x$screenviewsize $filename $screenviewfilename";
214 print $outhandle "$command\n" if ($verbosity > 2);
215 my $result = "";
216 $result = `$command 2>&1` ;
217 print $outhandle "$result\n" if ($verbosity > 3);
218
219 # get screenview dimensions, size and type
220 if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {
221 $doc_obj->add_metadata ($section, "ScreenWidth", $1);
222 $doc_obj->add_metadata ($section, "ScreenHeight", $2);
223 }
224
225 #add the screenview as an associated file ...
226 if (-e "$screenviewfilename") {
227 $doc_obj->associate_file("$screenviewfilename", "screenview.$screenviewtype",
228 "image/$screenviewtype",$section);
229 $doc_obj->add_metadata ($section, "ScreenType", $screenviewtype);
230 $doc_obj->add_metadata ($section, "Screen", "screenview.$screenviewtype");
231 } else {
232 print $outhandle "ImagePlug: couldn't find \"$screenviewfilename\"\n";
233 }
234 }
235
236 return $type;
237
238
239}
240
241
242# The ImagePlug read() function. This function does all the right things
243# to make general options work for a given plugin. It calls the process()
244# function which does all the work specific to a plugin (like the old
245# read functions used to do). Most plugins should define their own
246# process() function and let this read() function keep control.
247#
248# ImagePlug overrides read() because there is no need to read the actual
249# text of the file in, because the contents of the file is not text...
250#
251# Return number of files processed, undef if can't process
252# Note that $base_dir might be "" and that $file might
253# include directories
254
255sub read {
256 my $self = shift (@_);
257 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs) = @_;
258
259 my $outhandle = $self->{'outhandle'};
260
261 my $filename = &util::filename_cat($base_dir, $file);
262 return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
263 if ($filename !~ /$self->{'process_exp'}/ || !-f $filename) {
264 return undef;
265 }
266 print $outhandle "ImagePlug processing \"$filename\"\n"
267 if $self->{'verbosity'} > 1;
268
269 #if there's a leading directory name, eat it...
270 $file =~ s/^.*[\/\\]//;
271
272 # create a new document
273 my $doc_obj = new doc ($filename, "indexed_doc");
274 $doc_obj->set_OIDtype ($processor->{'OIDtype'});
275
276 #run convert to get the thumbnail and extract size and type info
277 my $result = run_convert($self, $filename, $file, $doc_obj);
278
279 if (!defined $result)
280 {
281 print "ImagePlug: couldn't process \"$filename\"\n";
282 return 0;
283 }
284
285 #create an empty text string so we don't break downstream plugins
286 my $text = "Dummy text to sidestep display bug.";
287
288 # include any metadata passed in from previous plugins
289 # note that this metadata is associated with the top level section
290 my $section = $doc_obj->get_top_section();
291 $self->extra_metadata ($doc_obj, $section, $metadata);
292
293 # do plugin specific processing of doc_obj
294 return undef unless defined ($self->process (\$text, $pluginfo, $base_dir,
295 $file, $metadata, $doc_obj));
296
297 # do any automatic metadata extraction
298 $self->auto_extract_metadata ($doc_obj);
299
300 # add an OID
301 $doc_obj->set_OID();
302 $doc_obj->add_text($section, $text);
303
304 # process the document
305 $processor->process($doc_obj);
306
307 # clean up temporary files - we do this here instead of in
308 # run_convert becuase associated files aren't actually copied
309 # until after process has been run.
310 if (defined $self->{'tmp_filename'} &&
311 -e $self->{'tmp_filename'}) {
312 &util::rm($self->{'tmp_filename'})
313 }
314 if (defined $self->{'tmp_filename2'} &&
315 -e $self->{'tmp_filename2'}) {
316 &util::rm($self->{'tmp_filename2'})
317 }
318 if (defined $self->{'tmp_filename3'} &&
319 -e $self->{'tmp_filename3'}) {
320 &util::rm($self->{'tmp_filename3'})
321 }
322
323 return 1;
324}
325
326# do plugin specific processing of doc_obj
327sub process {
328 my $self = shift (@_);
329 my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_;
330 my $outhandle = $self->{'outhandle'};
331
332 return 1;
333}
334
3351;
336
337
338
339
340
341
342
343
344
345
346
Note: See TracBrowser for help on using the repository browser.