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

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

Feature 1064 added : improve upload progress dialog box to display current operation and the rank of the photo being uploaded.

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