source: extensions/pLoader/trunk/src/Uploader/ImageList.pm @ 4760

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

Bug 1066 fixed: unexpected behaviour on resizing. Now rotate before resize.

  • Property svn:eol-style set to LF
File size: 34.6 KB
Line 
1# +-----------------------------------------------------------------------+
2# | pLoader - a Perl photo uploader for Piwigo                            |
3# +-----------------------------------------------------------------------+
4# | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
5# +-----------------------------------------------------------------------+
6# | This program is free software; you can redistribute it and/or modify  |
7# | it under the terms of the GNU General Public License as published by  |
8# | the Free Software Foundation                                          |
9# |                                                                       |
10# | This program is distributed in the hope that it will be useful, but   |
11# | WITHOUT ANY WARRANTY; without even the implied warranty of            |
12# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
13# | General Public License for more details.                              |
14# |                                                                       |
15# | You should have received a copy of the GNU General Public License     |
16# | along with this program; if not, write to the Free Software           |
17# | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
18# | USA.                                                                  |
19# +-----------------------------------------------------------------------+
20package Uploader::ImageList;
21use strict;
22use Carp;
23use base qw/Uploader::Object/;
24use Image::ExifTool qw(:Public);
25use Image::Magick;
26use File::Spec;
27use Uploader::Image;
28use Data::Dumper;
29use Storable;
30use Digest::MD5::File qw/file_md5_hex md5_hex/;
31use Wx::Locale qw/:default/;
32use Wx;
33
34# this class implements a collection of image files with associated data
35$|=1;
36__PACKAGE__->mk_accessors( 
37    qw/
38                thumb_size
39                preview_ratio
40                categories
41                type
42                filter
43                blur
44                quality
45                resize_w
46                resize_h
47                hd_filter
48                hd_blur
49                hd_quality
50                hd_w
51                hd_h
52                hd_interlace
53                prefix
54                author
55                count
56                new_files
57                storable_file
58                wx_thumb_size
59                current_image
60                images
61                image_selection
62                exif_metadata
63                wx_thumb_imglist
64                wx_thumb_dir
65                site_resized_dir
66                site_thumb_dir
67                userdata_dir
68                progress_msg
69                last_error_msg
70                default_photo_name
71                default_photo_name_method
72                default_name_prefix
73                SetNewFilesViewerRefreshCallback
74                SetNewFilesProgressCallback
75                SetNewFilesDisplayEndInfoCallback
76                YieldCallback
77                UploadImagesViewerCallback
78                progress_thumbnail_refresh
79                progress_msg_details_refresh
80                progress_msg_refresh
81                progressbar_refresh
82                progress_endinfo_refresh
83                ResizeCallback
84                upload_rejects
85                pwg
86                upload_high
87                upload_hd
88                remove_uploaded_from_selection
89                wx_quality
90                th_quality
91                auto_rotate
92                interlace
93                create_resized
94                use_exif_preview
95                image_sums
96                upload_image_sums
97                sums
98                version
99                imagelist_version
100                uploaded_images
101                watermark_activate
102                watermark_activate_pwg_high
103                watermark_text
104                watermark_text_size
105                watermark_position
106                watermark_y
107                watermark_x
108                watermark_color
109                gravity
110                rgbcolor
111                upload_msg
112                upload_selection_count
113                upload_uploaded_count
114                upload_rejected_count
115                upload_last_error
116                upload_error_content
117                upload_begin_time
118                upload_end_time
119                upload_duration
120                upload_file
121                upload_name
122                ReuploadCallback
123                reupload_action_files
124                reupload_action_properties
125                reupload_action_properties_m
126                reupload_not_ask
127                display_mode
128     /
129);
130
131
132sub Init {
133    my ( $self ) = @_;
134   
135    $self->uploaded_images([]);
136    $self->gravity(
137        { 
138            'Top'          => 'North',
139            'Left'         => 'West',
140            'Right'        => 'East',
141            'Bottom'       => 'South',
142            'Top left'     => 'NorthWest',
143            'Top right'    => 'NorthEast',
144            'Bottom left'  => 'SouthWest',
145            'Bottom right' => 'SouthEast',
146            'Center'       => 'Center',
147       }   
148    );   
149
150    $self->rgbcolor(
151        {
152            "White" => '#FFFFFF',
153            "Black" => '#000000',
154        }   
155    );
156   
157}
158
159sub _set_exif_tag {
160    my ( $self, $file, $tag, $newValue ) = @_;   
161
162  my $options = {};
163  # Create a new Image::ExifTool object
164  my $exifTool = new Image::ExifTool;
165
166  # Extract meta information from an image
167  $exifTool->ExtractInfo($file, $options);
168
169  # Set a new value for a tag
170  $exifTool->SetNewValue($tag, $newValue);
171
172  # Write new meta information to a file
173  $exifTool->WriteInfo($file);
174
175}
176
177
178sub _set_current_image_filepaths {
179    my ( $self ) = @_;
180
181    my $filename = sprintf(
182        "%s.%s",
183        $self->current_image->file_sum,
184        $self->type,
185    );
186
187
188    $self->current_image->wx_thumb_file( 
189        File::Spec->catfile(
190            $self->wx_thumb_dir,
191            $filename
192        )
193    );
194
195    $self->current_image->site_thumb_file( 
196        sprintf("%s.%s",
197            File::Spec->catfile(
198                $self->site_thumb_dir,
199                'thumbnail'
200            ),
201            $self->type
202        )
203    );
204
205}
206
207
208sub SetCurrentImage {
209    my ( $self, $indx ) = @_;   
210
211    $self->current_image(
212        $indx != -1 ? $self->GetImage($indx) : Uploader::Image->new()
213    );
214}
215
216
217sub SetNewFiles {
218    my ( $self, $files ) = @_;
219
220    $self->new_files( $files );
221
222    # if some files have been previously selected
223    my $i = scalar @{$self->sums};
224    #printf("SetNewFiles %s\n", $i);
225    my $count = 0;
226    $self->count($count);
227    my $errors = 0;
228
229    map {
230        my $info = $self->_read_exif_metatdata($_->{ANSIPathName});
231           my $is_new_image = $self->_add_image($_, $info, $i);   
232        $self->SetCurrentImage($i);
233        $self->_set_current_image_filepaths();
234
235        if($is_new_image){
236            #my $use_wx_resize = $self->_create_gui_preview($info);
237            $self->_create_gui_thumbnail();
238
239            # ok
240            if(!$@){
241                $self->progress_msg(gettext("Selection thumbnail created for %s"));
242            }
243            else {
244                $self->progress_msg("An error has occured when processing %s\n$@");
245                # remove from list
246                splice @{$self->sums}, $i, 1;
247                $errors++;
248            }
249       
250            $self->SetNewFilesProgressCallback->();
251        }
252        $i++;
253        $count++;
254        $self->count($count);
255        $self->SetNewFilesViewerRefreshCallback->();
256    }
257    @{$files};
258    $self->SetNewFilesDisplayEndInfoCallback->(
259        sprintf(
260            "%s : %s\n\n%s : %s",
261            gettext("photos added to the selection"),
262            $self->count,
263            gettext("errors"),
264            $errors,
265           
266        )
267    );
268   
269    $self->Store;
270   
271}
272
273sub _read_exif_metatdata {
274    my ( $self, $file ) = @_;
275   
276    # read exif metadata
277    my $info;
278    eval {
279        $info = ImageInfo( $file );
280    };
281    $info = {} if($@);
282   
283    $info;
284}
285
286# key is file path
287sub _add_image {
288    my ( $self, $file, $info, $i ) = @_;   
289
290    my $is_new_image;
291
292    # for legacy imagelist that do not have image_sums property
293    $self->image_sums(
294        {}
295    ) if !$self->image_sums;
296
297    my $sum = file_md5_hex($file->{ANSIPathName});
298
299    my $image;
300    if ( !exists $self->image_sums->{$sum} ){
301        #print "_add_image ", Dumper $file, "\n";
302        # append to image list
303        $image = Uploader::Image->new(
304        {
305                file              => $file->{ANSIPathName},
306                file_sum          => $sum,
307                site_name         => $self->_default_photo_name($file->{PathName}, $info, $i),
308                site_author       => $self->author,
309                exif_metadata     => $self->_select_exif_data($info),
310                add_rank          => $i,
311                site_categories   => [],
312                site_tags         => [],
313                site_high_file    => $file->{ANSIPathName},
314            }
315        );
316
317        $self->image_sums->{$sum} = $image ;
318        $is_new_image = 1;
319    } else {
320        $image = $self->image_sums->{$sum};
321    }
322
323       
324    $self->sums->[$i] = $sum ;
325
326    $is_new_image;
327}
328
329
330sub _default_photo_name {
331    my ( $self, $file, $info, $i ) = @_;
332   
333   
334    my $name;
335    my $create_date = $info->{CreateDate};
336    my $ext;
337    my ( $vol, $path, $filename ) = File::Spec->splitpath($file);
338    ( $filename, $ext ) = split /\.\w+$/, $filename;
339   
340    my ( $yyyy, $mm, $dd, $hh, $mi, $ss ) = split /[:\s]/, $create_date ;
341 
342    my $chrono = join('', $yyyy, $mm, $dd);
343    if('Prefix' eq $self->default_photo_name){
344        $name = $self->default_name_prefix
345    }
346    elsif('File name' eq $self->default_photo_name){
347        $name = $filename
348    }
349    elsif('File path and name' eq $self->default_photo_name){
350        $name = sprintf(
351            "%s", 
352            File::Spec->catfile($path, $filename), 
353        )       
354    }   
355    elsif('Prefix + rank number' eq $self->default_photo_name){
356        $name = sprintf(
357            "%s%s", 
358            $self->default_name_prefix, 
359            1+$i,
360        )       
361    }   
362    elsif('Rank number + prefix' eq $self->default_photo_name){
363        $name = sprintf(
364            "%s%s", 
365            1+$i,
366            $self->default_name_prefix, 
367        )       
368    }   
369    elsif('Prefix + create date chrono' eq $self->default_photo_name){
370        $name = sprintf(
371            "%s%s", 
372            $self->default_name_prefix, 
373            $chrono,
374        )       
375    }   
376    elsif('Create date chrono + prefix' eq $self->default_photo_name){
377        $name = sprintf(
378            "%s%s", 
379            $chrono,
380            $self->default_name_prefix, 
381        )       
382    }
383
384    $name;
385}
386
387
388sub _create_gui_thumbnail {
389    my ( $self ) = @_;
390
391     eval {
392        if(!$self->CreateGUIThumbnail())
393        {
394            $self->ResizeCallback->(
395                $self->current_image->file,
396                $self->current_image->wx_thumb_file,
397                $self->type,
398                $self->wx_thumb_size,
399                $self->wx_thumb_size,
400                $self->wx_quality,
401            );
402           
403        }
404     };
405}
406
407sub RemoveImageSelection {
408    my ( $self ) = @_;
409   
410    return if (! scalar @{$self->sums} );
411    return if (! defined $self->image_selection );
412   
413    $self->_remove_image_list($self->image_selection);
414    # clear image selection
415    $self->image_selection([]);
416}
417
418sub _remove_image_list {
419    my ( $self, $list ) = @_;
420    # the list is sorted, ascendant
421    # we reverse it to have
422    # higher first, and keep same indexes during remove
423    @$list = reverse @$list;     
424    map {
425        $self->DeleteImage($_);
426        splice @{$self->sums}, $_, 1 ;
427        $self->wx_thumb_imglist->Remove($_);
428        shift @$list;
429    }
430    @$list;
431}
432
433
434# used for display in GUI. has to fit a square box ( wxImageList )
435sub CreateGUIThumbnail {
436    my ( $self ) = @_;
437
438    my $rval = 0;
439    my $image = new Image::Magick;
440
441    my $size = $self->wx_thumb_size||100;
442
443    my $status = $image->Set(size=>sprintf("%sx%s", 2*$size, 2*$size));
444    warn "$status" if $status ;
445
446    $status = $image->ReadImage(
447        $self->current_image->file
448    );
449    warn "$status" if $status;
450    return $rval if $status;
451
452    $self->current_image->width(
453        $image->Get('width')
454    );
455    $self->current_image->height(
456        $image->Get('height')
457    );
458
459
460    # maximize size and keep aspect ratio
461    $status = $image->Thumbnail(
462        geometry=>sprintf("%s%s>", $size*$size, '@')
463    );
464    # to get adjusted to a square box
465    #$status = $image->Thumbnail(
466    #    geometry=>sprintf("%sx%s%s", $size, $size, '^')
467    #);
468    warn "$status" if $status;
469    return $rval if $status;
470
471#    causes strange behaviour with i18n -> yellow borders when local is other than EN
472#    $status = $image->Set(background=>"white");
473#    warn "$status" if $status ;
474
475    $status = $image->Set(Gravity=>"Center");
476    warn "$status" if $status ;
477
478    $image->Extent(
479        geometry=>sprintf("%sx%s", $size, $size),
480        gravity=>'center',
481    );
482   
483    $image->Set(
484        quality=>$self->wx_quality||90
485    );
486
487    $status = $image->Strip();
488    warn "$status" if $status ;
489
490    # exif from original image
491    my $orientation = $self->current_image->exif_metadata->{Orientation};
492   
493    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
494    if( $orientation =~ m/Rotate (\d+)/ ){
495        printf(
496            "Rotate %s\n",
497            $1
498        );
499   
500        $image->Rotate( degrees=>$1 ) if $self->auto_rotate;   
501    }
502   
503
504    $image->Write(
505        sprintf(
506            "%s:%s",
507            $self->type,
508            $self->current_image->wx_thumb_file,
509        )
510    );
511
512    undef $image;
513   
514    $rval = 1;
515   
516    return $rval;
517}
518
519
520
521
522sub CreateResized {
523    my ( $self ) = @_;
524   
525    my $rval = 1 ;
526
527
528    my $image = new Image::Magick;
529
530    my $status = $image->ReadImage(
531        $self->current_image->file
532    );
533    warn "$status" if $status ;
534    return 0 if $status;
535
536    my $w = $image->Get('width');
537    my $h = $image->Get('height');
538
539    $status = $image->Set(Gravity=>"Center");
540    warn "$status" if $status ;
541
542    # exif from original image
543    my $orientation = $self->current_image->exif_metadata->{Orientation};
544   
545    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
546    if( $orientation =~ m/Rotate (\d+)/ ){
547        printf(
548            "Rotate %s\n",
549            $1
550        );
551   
552        $image->Rotate( degrees=>$1 ) if $self->auto_rotate;   
553    }
554
555
556    #printf("resize with blur value %s\n", $self->blur);
557    $status = $image->Resize(
558        geometry => sprintf("%sx%s>", $self->resize_w, $self->resize_h), 
559        filter => sprintf("%s", $self->filter), 
560        blur => $self->blur
561    );
562    warn "$status" if $status ;
563    return 0 if $status;
564
565    #printf("resize with quality value %s\n", $self->quality);
566    $status = $image->Set(quality=>$self->quality);
567    warn "$status" if $status ;
568
569    $status = $image->Set(interlace=>$self->interlace);
570    warn "$status" if $status ;
571
572    $image->Write(
573        sprintf(
574            "%s:%s",
575            $self->type,
576            $self->current_image->site_resized_file,
577        )
578    );
579    warn "$status" if $status ;
580    return 0 if $status;
581   
582    undef $image;
583
584   
585    $rval = 0 if $status;
586
587    return $rval;
588}
589
590sub CreateThumbnail {
591    my ( $self ) = @_;
592   
593    #return 1 if( -e $self->current_image->site_thumb_file );
594   
595    my $rval = 1;
596
597    my $image = new Image::Magick;
598
599    my $status = $image->ReadImage(
600        $self->current_image->site_resized_file
601    );
602    warn "$status" if $status ;
603
604   
605    $status = $image->Resize(
606        geometry => sprintf(
607                                "%sx%s>", 
608                                $self->thumb_size, 
609                                $self->thumb_size
610                           ),
611    );
612    warn "$status" if $status ;
613
614    $status = $image->Set(Gravity=>"Center");
615    warn "$status" if $status ;
616
617    $status = $image->Set(quality=>$self->th_quality);
618    warn "$status" if $status ;
619
620    $status = $image->Strip();
621    warn "$status" if $status ;
622
623
624    $image->Write(
625        sprintf(
626            "%s:%s",
627            $self->type,
628            $self->current_image->site_thumb_file,
629        )
630    );
631   
632    undef $image;
633
634
635    $rval = 0 if $status;
636
637    return $rval;
638}
639
640
641
642sub _select_exif_data {
643    my ( $self, $exif ) = @_;
644
645    return {
646        map {
647            $_ => $exif->{$_},
648        }
649        qw/
650            CreateDate
651            ImageWidth
652            ImageHeight
653            Orientation
654            DateTimeOriginal
655            ISO
656            ExposureTime
657            ApertureValue
658            FocalLength
659            Lens
660            Exposure
661            Make
662            Model
663        /
664    };   
665}
666
667sub Store {
668    my ( $self ) = @_;
669   
670    my $data = $self->get_storable(
671        [ 
672            qw/
673                images
674                thumb_size
675                preview_ratio
676                type
677                filter
678                blur
679                quality
680                wx_quality
681                th_quality
682                prefix
683                author
684                count
685                resize_w
686                resize_h
687                hd_filter
688                hd_blur
689                hd_quality
690                hd_w
691                hd_h
692                hd_interlace
693                new_files
694                storable_file
695                wx_thumb_size
696                current_image
697                exif_metadata
698                wx_thumb_dir
699                site_resized_dir
700                site_thumb_dir
701                userdata_dir
702                progress_msg
703                default_photo_name
704                default_name_prefix
705                upload_high
706                upload_hd
707                remove_uploaded_from_selection
708                auto_rotate
709                interlace
710                create_resized
711                use_exif_preview
712                image_sums
713                sums
714                version
715                imagelist_version
716                watermark_activate
717                watermark_activate_pwg_high
718                watermark_text
719                watermark_text_size
720                watermark_position
721                watermark_y
722                watermark_x
723                watermark_color
724                reupload_action_files
725                reupload_action_properties
726                reupload_action_properties_m
727                display_mode
728            /
729        ] 
730   
731    );
732    eval {
733        store $data, $self->storable_file;
734    };
735    if($@){
736        print $@, "\n";   
737    }
738}
739
740
741
742sub UploadSelection {
743    my ( $self ) = @_;   
744
745    my $viewer_callback = $self->UploadImagesViewerCallback ;
746
747    $self->image_selection([]) if !defined $self->image_selection;
748    $self->upload_rejects(
749        []
750    );
751
752    $self->count(
753        1
754    );
755
756    $self->upload_uploaded_count(0);
757    $self->upload_rejected_count(0);
758    $self->upload_begin_time(time);
759    $self->upload_selection_count(scalar @{$self->image_selection});
760    # for re-upload management
761    $self->upload_image_sums( [
762            map { $self->GetImage($_)->file_sum }
763            @{$self->image_selection}
764        ] 
765    );
766
767    # check if already exist on server
768    my $uploaded = $self->pwg->IsAlreadyUploaded($self->upload_image_sums);
769    my @already_uploaded = grep { $_ } values %$uploaded ; 
770    $self->ReuploadCallback->() if ( scalar @already_uploaded and !$self->reupload_not_ask );
771
772   
773    foreach(@{$self->image_selection}) {
774    # current image object       
775        $self->current_image(
776            $self->GetImage($_)
777        ); 
778        # prepare resized, high, thumbnail
779        # if not already uploaded
780        $self->_set_site_resized_file();
781        $self-> _set_site_high_file ();
782        # photo metadata
783        $self->_upload_selection_prepare() if (!$uploaded->{$self->current_image->file_sum} or $self->reupload_action_files);
784        $self->_prepare_upload_properties();       
785
786        # transfert resized, high, thumbnail to site
787        my $status = $self->_upload_selection_transfert();
788        # log operations
789        $self->_upload_selection_log($status);
790        $self->count(
791            1+$self->count
792        );
793        # remove thumbnail, resized
794        # to make sure everything is clean
795        # keep site_high_file because it can be the original !!!
796        $self->_remove_resized_from_cache;
797    }
798
799    if($self->remove_uploaded_from_selection){
800        $self->_remove_image_list($self->uploaded_images);
801        $viewer_callback->();
802    }
803
804    $self->_upload_selection_final_log();
805}
806
807
808sub _remove_resized_from_cache {
809    my ( $self ) = @_;
810
811    unlink $self->current_image->site_thumb_file if -e $self->current_image->site_thumb_file;
812
813    map {
814        my $file = File::Spec->catfile(
815            $self->site_resized_dir,
816            sprintf(
817                "%s.%s",
818                 $_,
819                $self->type,
820            )
821        );
822        unlink $file if -e $file;
823    } qw /resized high/;
824
825
826}
827
828sub _upload_selection_prepare {
829    my ( $self ) = @_;
830
831    $self->progress_thumbnail_refresh->();
832    # PREPARE
833    $self->_set_upload_msg(gettext("Preparing resized image for"));
834    $self->_upload_progress();
835    #printf("resized %s\n", $self->create_resized);
836    if( $self->create_resized ){
837        $self->_create_site_resized_file();
838        $self->_set_upload_msg(gettext("Resized image done for"));
839        $self->_upload_progress();
840    }
841    # the original is at the right size, no need to create a resize
842    else {
843        #printf("original no resized %s\n", $self->create_resized);
844        $self->current_image->site_resized_file(
845            $self->current_image->file,
846        );
847    }
848
849    my $decode = {
850        'No' => 0,
851        'Yes, use HD resized of the original photo' => 'HD',
852        'Yes, use a copy of the original photo' => 'ORIGINAL',
853    };   
854    #printf("upload HD %s\n", $self->upload_hd);
855    $self->upload_high(
856        $decode->{$self->upload_hd}
857    );
858    #printf("upload High %s\n", $self->upload_high);
859   
860    # if upload high, rotate a copy of original file
861    if($self->upload_high){
862        $self->CreateHigh();
863        $self->_set_upload_msg(gettext("HD image done for"));
864        $self->_upload_progress();
865    }
866
867    eval {
868        $self->CreateThumbnail();
869    };
870    $self->_set_upload_msg(gettext("Thumbnail image done for"));
871    $self->_upload_progress();
872
873
874}
875
876sub _upload_progress {
877    my ( $self, $value ) = @_;
878
879    eval {
880        $self->progress_msg_refresh->(
881            $self->upload_msg
882        );
883        # set current image thumbnail
884          # update upload progress dialog
885        #$self->progressbar_refresh->($value);
886    };
887    # user cancelled : dialog box is destroyed
888    croak gettext("Upload cancelled"), " .", $@ if $@ ;
889
890
891}
892
893sub _set_upload_msg {
894    my ( $self, $msg, $errmsg ) = @_;
895
896    $self->upload_msg(
897        sprintf(
898            "%s : %s - %s\n\n%s %s %s %s\n%s",
899            $msg,
900            $self->upload_file,
901            $self->upload_name,
902            gettext("Photo"),
903            $self->count,
904            gettext("on"),
905            $self->upload_selection_count,
906            $errmsg
907        )
908    );
909}
910
911sub _upload_selection_transfert {
912    my ( $self ) = @_;
913
914    $self->_set_upload_msg(gettext("Uploading"));
915    $self->_upload_progress(0);
916
917    # UPLOAD
918    my ( $status, $status_msg, $content ) = $self->pwg->UploadImage(
919        { 
920            yield=>$self->YieldCallback, 
921            bar=>$self->progressbar_refresh, 
922            msg=>$self->progress_msg_refresh,
923            msg_details=>$self->progress_msg_details_refresh,
924            resized_msg=>gettext("Uploading resized"),
925            thumbnail_msg=>gettext("Uploading thumbnail"),
926            highdef_msg=>gettext("Uploading high definition"),
927            checksum_msg=>gettext("Checksum for"),
928            original_sum=>$self->current_image->file_sum,
929        } 
930    );
931    my $ok = 0;
932    # HTTP REQUEST OK
933    if ( $status ){
934        # PIWIGO RESULT ( HTTP may be ok while Piwigo is not )
935        $ok = 'fail' eq $content->{stat} ? 0 : 1;
936    }
937    else{
938        Wx::LogMessage(
939            "%s %s : %s",
940            gettext("Communication error with"),
941            $self->pwg->site_url,
942            $status_msg,
943        );
944    }
945    $self->upload_last_error(
946        $status_msg
947    );
948
949    $self->upload_error_content(
950        $content
951    );
952
953    $ok;
954}
955
956sub _upload_selection_log {
957    my ( $self, $ok ) = @_;
958
959    if($ok){
960        $self->_set_upload_msg(gettext("Uploaded"));
961        $self->_upload_progress(0);
962        push @{$self->uploaded_images}, $_;
963        $self->upload_uploaded_count(
964            1+$self->upload_uploaded_count       
965        );
966    } else {
967        $self->_set_upload_msg(gettext("An error has occured"), Dumper($self->upload_error_content));
968        $self->upload_rejected_count(
969            1+$self->upload_rejected_count
970        );
971    }   
972       
973}
974
975sub _upload_selection_final_log {
976    my ( $self ) = @_;
977
978    $self->upload_end_time(time);
979    $self->upload_duration(
980        $self->upload_end_time - $self->upload_begin_time
981    );
982
983    $self->progress_endinfo_refresh->(
984        sprintf(
985            "%s : %s\n\n%s : %s\n\n%s : %s\n\n\n%s : %s %s",
986            gettext("images processed"),
987            $self->count - 1,
988            gettext("images uploaded"),
989            $self->upload_uploaded_count,
990            gettext("images in errors and not uploaded"),
991            $self->upload_rejected_count,
992            gettext("Duration"),
993            $self->upload_duration,
994            gettext("seconds"),
995        )
996    );
997}
998
999sub _set_site_resized_file {
1000    my ( $self ) = @_;
1001
1002    my ( $vol, $dir, $file ) = File::Spec->splitpath(
1003        $self->current_image->file
1004    );
1005
1006    $self->upload_file(
1007        $file
1008    );
1009       
1010    $self->upload_name(
1011        $self->current_image->site_name
1012    );
1013    my $filename = $self->current_image->file_sum ;
1014
1015    # lately defined to make sure we have the last global properties ( resize_w, resize_h )
1016    $self->current_image->site_resized_file( 
1017        File::Spec->catfile(
1018            $self->site_resized_dir,
1019            sprintf(
1020                "%s.%s",
1021                'resized',
1022                $self->type,
1023            )
1024        )
1025    );
1026    printf("_set_site_resized_file %s\n", $self->current_image->site_resized_file);
1027}
1028
1029sub _create_site_resized_file {
1030    my ( $self ) = @_;
1031
1032    eval {
1033        if(!$self->CreateResized()){
1034            $self->_create_resized_fallback();
1035        };
1036
1037        $self->_set_exif_tag(
1038            $self->current_image->site_resized_file,
1039            'Orientation',
1040            'Horizontal (normal)',
1041        ) if $self->auto_rotate;
1042
1043        $self->CreateWatermark(
1044            $self->watermark_text,
1045            $self->watermark_text_size,
1046            $self->watermark_position,
1047            $self->watermark_x,
1048            $self->watermark_y,
1049            $self->watermark_color,
1050            $self->current_image->site_resized_file
1051        ) if $self->watermark_activate;
1052    }
1053}
1054
1055sub _create_resized_fallback {
1056    my ( $self ) = @_;
1057    # use wx builtin rescale if IM fails
1058    printf("CreateResized failed %s. Use ResizeCallback\n", $@);
1059    # use method provided by the caller
1060    # source, target, type, ratio, width, $height
1061    $self->ResizeCallback->(
1062        $self->current_image->file,
1063        $self->current_image->site_resized_file,
1064        $self->type,
1065        $self->resize_w,
1066        $self->resize_h,
1067        $self->quality,
1068    );
1069               
1070    $self->RotateImage(
1071        $self->current_image->site_resized_file,
1072    ) if $self->auto_rotate;
1073}
1074
1075# if we need to rotate
1076sub CreateHigh {
1077    my ( $self ) = @_;
1078
1079    #printf("CreateHigh %s\n", $self->upload_high);
1080    my $bModifyOriginal;
1081    my $bRotate;
1082    my $bAddWatermark;
1083    my $bResize;
1084    my $orientation = $self->current_image->exif_metadata->{Orientation};
1085    my $degrees;
1086   
1087    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1088    if( $self->auto_rotate and $orientation =~ m/Rotate (\d+)/ ){
1089        $bModifyOriginal = 1;
1090        $bRotate = 1;
1091        $degrees = $1;
1092    }
1093
1094    if( $self->watermark_activate_pwg_high ){
1095        $bModifyOriginal = 1;
1096        $bAddWatermark = 1;
1097    }
1098   
1099    # HD resize
1100    if('HD' eq $self->upload_high){
1101        $bModifyOriginal = 1;
1102        $bResize = 1;
1103    }
1104
1105    if($bModifyOriginal){
1106
1107        my $image = Image::Magick->new();
1108        # we read original
1109        my $status = $image->Read(
1110            $self->current_image->file
1111        );
1112        warn "$status ", $self->current_image->file, "\n" if $status ;
1113        return 0 if $status;
1114
1115        if($bRotate){
1116            $image->Rotate( degrees=>$degrees );   
1117        }       
1118        $image->Write(
1119            $self->current_image->site_high_file
1120        );
1121        warn "$status ", $self->current_image->site_high_file, "\n" if $status ;
1122        return 0 if $status;
1123
1124        if($bResize){
1125            $status = $image->Resize(
1126                geometry => sprintf("%sx%s>", $self->hd_w, $self->hd_h), 
1127                filter => sprintf("%s", $self->hd_filter), 
1128                blur => $self->hd_blur
1129            );
1130            warn "$status" if $status ;
1131            return 0 if $status;
1132        }
1133       
1134        #printf("resize with quality value %s\n", $self->quality);
1135        $status = $image->Set(quality=>$self->quality);
1136        warn "$status" if $status ;
1137
1138        $status = $image->Set(interlace=>$self->interlace);
1139        warn "$status" if $status ;
1140       
1141       
1142        undef $image;
1143
1144        if($bAddWatermark){
1145          my $file_out = $self->current_image->site_high_file;
1146          $self->CreateWatermark(
1147             $self->watermark_text,
1148                $self->watermark_text_size,
1149                $self->watermark_position,
1150                $self->watermark_x,
1151                $self->watermark_y,
1152                $self->watermark_color,
1153                $file_out
1154            );
1155        }
1156
1157
1158        $self->_set_exif_tag(
1159            $self->current_image->site_high_file,
1160            'Orientation',
1161            'Horizontal (normal)',
1162        );
1163
1164        # Now all images that need to be rotated are done. Update exif
1165        $self->current_image->exif_metadata->{Orientation} = 'Horizontal (normal)';
1166
1167
1168    }
1169    else{
1170        # high file is the original file
1171        $self->current_image->site_high_file(
1172            $self->current_image->file
1173        );
1174        #printf("site high file %s\n", $self->current_image->site_high_file);
1175    }
1176
1177    return 1;
1178}
1179
1180# file name for original copy
1181# we do not need the original file name
1182sub _set_site_high_file {
1183        my ( $self ) = @_;
1184
1185        my ( $vol, $dir, $file ) = File::Spec->splitpath(
1186            $self->current_image->file
1187        );
1188   
1189        my ( $filename, $ext ) = split /\./, $file ;
1190   
1191        # high_file is a resized of original
1192        $self->current_image->site_high_file( 
1193            File::Spec->catfile(
1194                $self->site_resized_dir,
1195                sprintf(
1196                    "%s.%s",
1197                     'high',
1198                    $self->type,
1199                )
1200            )
1201        );
1202}
1203
1204sub CreateWatermark {
1205    my ( $self, $text, $text_size, $position, $x, $y, $color, $file_out ) = @_;
1206   
1207    my $rval = 1 ;
1208    my $gravity = $self->gravity->{$position};
1209    my $fill = $self->rgbcolor->{$color};
1210
1211    # debug
1212    #printf("Create watermark %s\n", $file_out);
1213
1214   
1215
1216    my $image = new Image::Magick;
1217   
1218    my $status = $image->ReadImage(
1219        $file_out
1220    );     
1221
1222    my $ratio = $image->Get('height')/($self->resize_h||$image->Get('height'));
1223    $ratio||=1;
1224    $text ||="Your watermark";
1225    $image->Annotate(
1226        pointsize => $text_size*$ratio,
1227        fill => $fill,
1228        x => $x*$ratio,
1229        y => $y*$ratio,
1230        text => $text,
1231        gravity => $gravity,
1232    );
1233                     
1234    $image->Write(
1235        sprintf(
1236            "%s:%s",
1237            $self->type,
1238            $file_out,
1239        )
1240    );
1241}
1242
1243sub _prepare_upload_properties {
1244    my ( $self ) = @_;
1245
1246    # set default values only if not defined
1247    # || operator is not used because 0 is a choice value
1248    # and woukd replace a valid choice with a default value
1249    $self->reupload_action_files(1) 
1250        unless defined $self->reupload_action_files;
1251
1252    $self->pwg->reupload_action_properties(1)
1253        unless defined $self->pwg->reupload_action_properties;
1254
1255    $self->pwg->reupload_action_properties_m(1)
1256        unless defined $self->pwg->reupload_action_properties_m;
1257
1258    $self->pwg->reupload_action_files(
1259        $self->reupload_action_files
1260    );
1261    $self->pwg->reupload_action_properties(
1262        $self->reupload_action_properties
1263    );
1264
1265    $self->pwg->reupload_action_properties_m(
1266        $self->reupload_action_properties_m
1267    );
1268   
1269    $self->pwg->upload_high(
1270        $self->upload_high
1271    );
1272
1273    $self->pwg->site_high_file(
1274        $self->current_image->site_high_file
1275    );
1276
1277    $self->pwg->site_resized_file(
1278        $self->current_image->site_resized_file
1279    );
1280
1281    $self->pwg->site_thumb_file(
1282        $self->current_image->site_thumb_file
1283    );
1284
1285    $self->pwg->site_author(
1286        $self->current_image->site_author
1287    );
1288
1289    $self->pwg->site_comment(
1290        $self->current_image->site_comment
1291    );
1292
1293    $self->pwg->site_image_name(
1294        $self->current_image->site_name
1295    );
1296
1297    $self->pwg->site_img_date_creation(
1298        substr($self->current_image->create_date, 0, 10)
1299    );
1300
1301    $self->pwg->privacy_level(
1302        $self->current_image->privacy_level
1303    );
1304   
1305    $self->current_image->site_categories(
1306        $self->categories
1307    );
1308
1309    $self->pwg->categories(
1310        sprintf(
1311            "%s",
1312            join(';', @{$self->categories})
1313        )
1314    );
1315
1316    $self->pwg->site_tags(
1317        join(',', @{$self->current_image->site_tags})
1318    );
1319
1320   
1321}
1322
1323# read Orientation exif tag from original image
1324# apply rotation to $file image
1325sub RotateImage {
1326    my ( $self, $file ) = @_;
1327   
1328    # exif from original image
1329    my $orientation = $self->current_image->exif_metadata->{Orientation};
1330
1331    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1332    if( $orientation =~ m/Rotate (\d+)/ ){
1333        printf(
1334            "Rotate %s\n",
1335            $1
1336        );
1337
1338        my $image = Image::Magick->new();
1339       
1340        # read resized file
1341        my $status = $image->Read(
1342            $file
1343        );
1344        warn "$status ", $file, "\n" if $status ;
1345        return 0 if $status;
1346   
1347        $image->Rotate( degrees=>$1 );   
1348       
1349        # write resized file
1350        $image->Write(
1351            $file
1352        );
1353        warn "$status ", $file, "\n" if $status ;
1354        return 0 if $status;
1355       
1356        undef $image;
1357   
1358    }   
1359    return 1;
1360}
1361
1362sub GetImage {
1363    my ( $self, $indx ) = @_;
1364   
1365    my $sum = $self->sums->[$indx];
1366
1367    $self->image_sums->{$sum};
1368}
1369
1370sub DeleteImage {
1371    my ( $self, $indx ) = @_;
1372   
1373    my $sum = $self->sums->[$indx];
1374
1375    delete $self->image_sums->{$sum};
1376}
1377
1378
13791;
Note: See TracBrowser for help on using the repository browser.