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

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

Feature 1055 added : preparation of high definition images ( HD ).

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