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

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

Remove use of Class::Path::Unicode

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