source: extensions/pLoader/trunk/src/Uploader/ResizeWorker.pm @ 6707

Last change on this file since 6707 was 6707, checked in by ronosman, 14 years ago

use tranfer error messages in progress list. various bug fixes.

File size: 13.3 KB
Line 
1package Uploader::ResizeWorker;
2use threads;
3use threads::shared;
4use strict;
5use base qw/Uploader::Object/;
6use Image::Magick;
7use Data::Dumper;
8
9$|=1;
10
11__PACKAGE__->mk_accessors(qw/
12    preferences
13    wx_thumb_dir
14    thumb_dir
15    resized_dir
16    write_type
17    progress_event
18    done_event
19    event_handler
20    cancel_event
21/);
22
23
24sub Init {
25    my ( $self ) =@_;
26
27}
28
29
30sub cancel_image {
31    my ( $self, $image ) = @_;
32   
33    #must check if $image is a valid hash
34    return unless 'HASH' eq ref $image;
35    return unless $image->{image_id};
36
37    $self->log_image_progress(
38        $image,
39        $self->localized_msg->{"cancelled"},
40        0,
41    );
42}
43
44
45sub process_image {
46    my ( $self, $handler, $progress_event, $resize_done_event, $image ) = @_;
47
48    $self->event_handler(
49        $handler
50    );
51
52
53    $self->progress_event(
54        $progress_event
55    );
56
57    $self->done_event(
58        $resize_done_event
59    );
60
61    $self->resize_image($image);
62    $self->process_high_image($image);
63    $self->thumbnail_image($image);
64
65    $self->post_image_done_event($image);
66}
67
68
69sub post_image_progress_event {
70    my ( $self, $image ) = @_;
71
72    $self->post_image_event(
73        $self->progress_event,
74        $image
75    );
76}
77
78
79sub post_image_done_event {
80    my ( $self, $image ) = @_;
81
82    $image->{status}   = $self->localized_msg->{"prepared, waiting for transfer"};
83    $image->{progress} = 25;
84
85    $self->post_image_event(
86        $self->done_event,
87        $image
88    );
89}
90
91
92sub post_image_cancel_event {
93    my ( $self, $image ) = @_;
94
95    $image->{status}   = "cancelled";
96    $image->{progress} = 0;
97
98    $self->post_image_event(
99        $self->cancel_event,
100        $image
101    );
102}
103
104
105
106
107sub post_image_event {
108    my ( $self, $event_type, $image ) = @_;
109
110    my $thread_event = Wx::PlThreadEvent->new(
111        -1,
112        $event_type,
113        shared_clone($image)
114    );
115
116    eval {
117        Wx::PostEvent($self->event_handler, $thread_event);
118    }
119
120}
121
122
123sub resize_image {
124    my ( $self, $image ) = @_;
125
126    $self->log_image_progress(
127        $image,
128        $self->localized_msg->{"preparing web size"},
129        5,
130    );
131
132    my $preferences = $image->{preferences};
133
134    if( $preferences->{create_resized} ){
135        $self->create_resized($image);
136    }
137    # the original is at the right size, no need to create a resize
138    else {
139        #printf("original no resized %s\n", $self->create_resized);
140        $image->{site_resized_file} = $image->{file};
141    }
142
143    $self->log_image_progress(
144        $image,
145        $self->localized_msg->{"web size prepared"},
146        10,
147    );
148
149}
150
151
152sub log_image_progress {
153    my ( $self, $image, $status, $value ) = @_;
154
155    $image->{status}   = $status;
156    $image->{progress} = $value;
157    $self->post_image_progress_event($image);
158}
159
160
161sub process_high_image {
162    my ( $self, $image ) = @_;
163
164    my $decode = {
165        'No' => 0,
166        'Yes, use HD resized of the original photo' => 'HD',
167        'Yes, use a copy of the original photo' => 'ORIGINAL',
168    };
169
170    my $preferences = $image->{preferences};
171    $image->{upload_high} = $decode->{$preferences->{upload_hd}};
172    # if upload high, rotate a copy of original file
173    if($image->{upload_high}){
174        $self->create_high($image);
175    }
176}
177
178
179# $image is a hash, not an object
180sub create_resized {
181    my ( $self, $image ) = @_;
182
183    my $rval = 1 ;
184
185    $image->{site_resized_file} = File::Spec->catfile(
186        $self->resized_dir,
187        sprintf(
188            "%s.%s.%s",
189            $image->{image_id},
190            $image->{global_rank},
191            $self->write_type,
192        ),
193    );
194
195    my $imgk = new Image::Magick;
196
197    my $status = $imgk->ReadImage(
198        $image->{file}
199    );
200    warn "$status" if $status ;
201    return 0 if $status;
202
203    my $w = $imgk->Get('width');
204    my $h = $imgk->Get('height');
205
206    $status = $imgk->Set(Gravity=>"Center");
207    warn "$status" if $status ;
208
209    # exif from original image
210    my $orientation = $image->{exif_metadata}{Orientation};
211    my $preferences = $image->{preferences};
212   
213    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
214    if( $orientation =~ m/Rotate (\d+)/ ){
215        printf(
216            "Rotate %s\n",
217            $1
218        );
219   
220        $imgk->Rotate( degrees=>$1 ) if $preferences->{auto_rotate};   
221    }
222
223
224    #printf("resize with blur value %s\n", $self->blur);
225    $status = $imgk->Resize(
226        geometry => sprintf(
227            "%sx%s>",
228            $preferences->{resize_w},
229            $preferences->{resize_h}
230        ),
231        filter => sprintf(
232            "%s",
233            $preferences->{filter}
234        ), 
235        blur => $preferences->{blur}
236    );
237    warn "$status" if $status ;
238    return 0 if $status;
239
240    #printf("resize with quality value %s\n", $self->quality);
241    $status = $imgk->Set(quality=>$preferences->{quality});
242    warn "$status" if $status ;
243
244    $status = $imgk->Set(interlace=>$preferences->{interlace});
245    warn "$status" if $status ;
246
247    $imgk->Write(
248        sprintf(
249            "%s:%s",
250            $self->write_type,
251            $image->{site_resized_file},
252        )
253    );
254    warn "$status" if $status ;
255    return 0 if $status;
256   
257    undef $imgk;
258
259   
260    $rval = 0 if $status;
261
262    return $rval;
263}
264
265# $image is a hash, not an object
266sub thumbnail_image {
267    my ( $self, $image ) = @_;
268   
269    my $rval = 1;
270
271    $image->{site_thumb_file} = File::Spec->catfile(
272        $self->thumb_dir,
273        sprintf(
274            "%s.%s.%s",
275            $image->{image_id},
276            $image->{global_rank},
277            $self->write_type,
278        ),
279    );
280
281
282    my $imgk = new Image::Magick;
283
284    my $status = $imgk->ReadImage(
285        $image->{site_resized_file}
286    );
287    warn "$status" if $status ;
288
289    my $preferences = $image->{preferences};
290    my $pattern = $preferences->{thumbnail_shape_square} ?
291        "%sx%s^" :
292        "%sx%s>" ;
293    $status = $imgk->Resize(
294        geometry => sprintf(
295            $pattern, 
296            $preferences->{thumb_size}, 
297            $preferences->{thumb_size}
298        ),
299    );
300    warn "$status" if $status ;
301
302    $status = $imgk->Set(Gravity=>"Center");
303    warn "$status" if $status ;
304
305    $status = $imgk->Crop(
306        geometry=>sprintf(
307            "%sx%s+0+0",
308            $preferences->{thumb_size},
309            $preferences->{thumb_size}
310        )
311    ) if $preferences->{thumbnail_shape_square};
312
313
314    $status = $imgk->Set(quality=>$preferences->{th_quality});
315    warn "$status" if $status ;
316
317    $status = $imgk->Strip();
318    warn "$status" if $status ;
319
320
321    $imgk->Write(
322        sprintf(
323            "%s:%s",
324            $self->write_type,
325            $image->{site_thumb_file},
326        )
327    );
328   
329    undef $image;
330
331
332    $rval = 0 if $status;
333
334    return $rval;
335}
336
337
338sub create_high {
339    my ( $self, $image ) = @_;
340
341    $self->log_image_progress(
342        $image,
343        $self->localized_msg->{"preparing high"},
344        15,
345    );
346
347    $self->set_site_high_file($image);
348
349    my $bModifyOriginal;
350    my $bRotate;
351    my $bAddWatermark;
352    my $bResize;
353    my $orientation = $image->{exif_metadata}{Orientation};
354    my $degrees;
355   
356    my $preferences = $image->{preferences};
357    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
358    if( $preferences->{auto_rotate} and $orientation =~ m/Rotate (\d+)/ ){
359        $bModifyOriginal = 1;
360        $bRotate = 1;
361        $degrees = $1;
362    }
363
364    if( $preferences->{watermark_activate_pwg_high} ){
365        $bModifyOriginal = 1;
366        $bAddWatermark = 1;
367    }
368   
369    # HD resize
370    if('HD' eq $image->{upload_high}){
371        $bModifyOriginal = 1;
372        $bResize = 1;
373    }
374
375    if($bModifyOriginal){
376
377        my $imgk = Image::Magick->new();
378        # we read original
379        my $status = $imgk->Read(
380            $image->{file}
381        );
382        warn "$status ", $image->{file}, "\n" if $status ;
383        return 0 if $status;
384
385        if($bRotate){
386            $imgk->Rotate( degrees=>$degrees );   
387        }       
388        $imgk->Write(
389            $image->{site_high_file}
390        );
391        warn "$status ", $image->{site_high_file}, "\n" if $status ;
392        return 0 if $status;
393
394        if($bResize){
395            $status = $imgk->Resize(
396                geometry => sprintf(
397                    "%sx%s>",
398                    $preferences->{hd_w},
399                    $preferences->{hd_h}
400                ), 
401                filter => sprintf(
402                    "%s",
403                    $preferences->{hd_filter}
404                ), 
405                blur => $preferences->{hd_blur}
406            );
407            warn "$status" if $status ;
408            return 0 if $status;
409        }
410       
411        #printf("resize with quality value %s\n", $self->quality);
412        $status = $imgk->Set(quality=>$preferences->{quality});
413        warn "$status" if $status ;
414
415        $status = $imgk->Set(interlace=>$preferences->{interlace});
416        warn "$status" if $status ;
417       
418       
419        undef $imgk;
420
421        if($bAddWatermark){
422            my $file_out = $image->{site_high_file};
423            $self->create_watermark(
424                $preferences->{watermark_text},
425                $preferences->{watermark_text_size},
426                $preferences->{watermark_position},
427                $preferences->{watermark_x},
428                $preferences->{watermark_y},
429                $preferences->{watermark_color},
430                $file_out
431            );
432        }
433
434        $self->set_file_exif_tag(
435            $image->{site_high_file},
436            'Orientation',
437            'Horizontal (normal)',
438        );
439
440        # Now all images that need to be rotated are done. Update exif
441        $image->{exif_metadata}{Orientation} = 'Horizontal (normal)';
442
443
444    }
445    else{
446        # high file is the original file
447        $image->{site_high_file} = $image->{file};
448        #printf("site high file %s\n", $self->current_image->site_high_file);
449    }
450    $self->log_image_progress(
451        $image,
452        $self->localized_msg->{"high prepared"},
453        25,
454    );
455
456    return 1;
457
458}
459
460
461sub set_site_high_file {
462    my ( $self, $image ) = @_;
463
464    my ( $vol, $dir, $file ) = File::Spec->splitpath(
465        $image->{file}
466    );
467   
468    my ( $filename, $ext ) = split /\./, $file ;
469   
470    # high_file is a resized of original
471    $image->{site_high_file} = File::Spec->catfile(
472        $self->resized_dir,
473        sprintf(
474            "%s_high.%s.%s",
475            $image->{image_id},
476            $image->{global_rank},
477            $self->write_type,
478        ),
479    );
480}
481
482
483sub set_file_exif_tag {
484    my ( $self, $file, $tag, $newValue ) = @_;   
485
486    my $options = {};
487    # Create a new Image::ExifTool object
488    my $exifTool = new Image::ExifTool;
489
490    # Extract meta information from an image
491    $exifTool->ExtractInfo($file, $options);
492
493    # Set a new value for a tag
494    $exifTool->SetNewValue($tag, $newValue);
495
496    # Write new meta information to a file
497    $exifTool->WriteInfo($file);
498
499}
500
501
502# used for display in GUI. has to fit a square box ( wxImageList )
503# $image is an object
504sub create_wx_thumbnail {
505    my ( $self, $image ) = @_;
506
507
508    $image->wx_thumb_file( 
509        File::Spec->catfile(
510            $self->wx_thumb_dir,
511            sprintf(
512                "%s.%s.%s",
513                $image->image_id,
514                $image->global_rank,
515                $self->write_type,
516            ),
517        )
518    );
519
520
521    my $rval = 0;
522    my $imgk = new Image::Magick;
523
524    my $preferences = $image->{preferences};
525    my $size = $preferences->{wx_thumb_size}||100;
526
527    my $status = $imgk->Set(size=>sprintf("%sx%s", 2*$size, 2*$size));
528    warn "$status" if $status ;
529
530    $status = $imgk->ReadImage(
531        $image->file
532    );
533    warn "$status" if $status;
534    return $rval if $status;
535
536    # maximize size and keep aspect ratio
537    $status = $imgk->Thumbnail(
538        geometry=>sprintf("%s%s>", $size*$size, '@')
539    );
540    # to get adjusted to a square box
541    #$status = $image->Thumbnail(
542    #    geometry=>sprintf("%sx%s%s", $size, $size, '^')
543    #);
544    warn "$status" if $status;
545    return $rval if $status;
546
547    $status = $imgk->Set(Gravity=>"Center");
548    warn "$status" if $status ;
549
550    $imgk->Extent(
551        geometry=>sprintf("%sx%s", $size, $size),
552        gravity=>'center',
553    );
554   
555    $imgk->Set(
556        quality=>$preferences->{wx_quality}||90
557    );
558
559    $status = $imgk->Strip();
560    warn "$status" if $status ;
561
562    # exif from original image
563    my $orientation = $image->exif_metadata->{Orientation};
564   
565    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
566    if( $orientation =~ m/Rotate (\d+)/ ){
567        printf(
568            "Rotate %s\n",
569            $1
570        );
571   
572        $imgk->Rotate( degrees=>$1 ) if $preferences->{auto_rotate};   
573    }
574   
575
576    $imgk->Write(
577        sprintf(
578            "%s:%s",
579            $self->write_type,
580            $image->wx_thumb_file,
581        )
582    );
583
584    undef $imgk;
585   
586    $rval = 1;
587   
588    return $rval;
589}
590
591
5921;
Note: See TracBrowser for help on using the repository browser.