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

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

Bug 1219 fixed : property values must be language independant.

  • Property svn:eol-style set to LF
File size: 33.3 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            'Top'          => 'North',
115            'Left'         => 'West',
116            'Right'        => 'East',
117            'Bottom'       => 'South',
118            'Top left'     => 'NorthWest',
119            'Top right'    => 'NorthEast',
120            'Bottom left'  => 'SouthWest',
121            'Bottom right' => 'SouthEast',
122            'Center'       => 'Center',
123       }   
124    );   
125
126    $self->rgbcolor(
127        {
128            "White" => '#FFFFFF',
129            "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('Prefix' eq $self->default_photo_name){
347        $name = $self->default_name_prefix
348    }
349    elsif('File name' eq $self->default_photo_name){
350        $name = $filename
351    }
352    elsif('File path and name' eq $self->default_photo_name){
353        $name = sprintf(
354            "%s", 
355            File::Spec->catfile($path, $filename), 
356        )       
357    }   
358    elsif('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('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('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('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.