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

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

Bug 1213 fixed. Accented characters in file and path names make pLoader Linux crash.

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