source: extras/pLoader/trunk/src/Uploader/ImageList.pm @ 3177

Last change on this file since 3177 was 3177, checked in by ronosman, 15 years ago

Features 914, 920, 921, 924 added ( sorry plg, it's a global commit ). Add an option to upload an already resized image. In that case, pLoader does not create any resized image and uploads original as a resized. Add properties to define custom preview ( option to not use exif preview and create a preview based on a preview ratio ).

  • Property svn:eol-style set to LF
File size: 25.1 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;
30# this class implements a collection of image files with associated data
31$|=1;
32__PACKAGE__->mk_accessors( 
33    qw/
34                thumb_size
35                preview_ratio
36                categories
37                type
38                filter
39                blur
40                quality
41                prefix
42                author
43                count
44                resize_w
45                resize_h
46                new_files
47                storable_file
48                wx_thumb_size
49                current_image
50                images
51                image_selection
52                exif_metadata
53                wx_thumb_imglist
54                wx_thumb_dir
55                preview_dir
56                site_resized_dir
57                site_thumb_dir
58                userdata_dir
59                progress_msg
60                last_error_msg
61                default_name_prefix
62                SetNewFilesViewerRefreshCallback
63                SetNewFilesProgressCallback
64                SetNewFilesDisplayEndInfoCallback
65                UploadImagesViewerCallback
66                progress_thumbnail_refresh
67                progress_msg_refresh
68                progressbar_refresh
69                progress_endinfo_refresh
70                ResizeCallback
71                upload_rejects
72                pwg
73                upload_high
74                wx_quality
75                th_quality
76                auto_rotate
77                interlace
78                create_resized
79                use_exif_preview
80     /
81);
82
83
84sub Init {
85    my ( $self ) = @_; 
86}
87
88
89
90# save exif preview image if available
91# otherwise create a preview image
92sub _write_preview_image {
93    my ( $self, $imagedata ) = @_;
94
95
96    # If PreviewImage is available, we use it
97    if(defined $imagedata ) {
98        eval {
99            open PREVIEW_FILE, ">", $self->current_image->preview_file ;
100            binmode PREVIEW_FILE;
101            print PREVIEW_FILE $$imagedata;
102            close PREVIEW_FILE;
103        };
104        $self->last_error_msg($@) if $@;
105    }
106   
107}
108
109
110sub _set_exif_tag {
111    my ( $self, $file, $tag, $newValue ) = @_; 
112
113  my $options = {};
114  # Create a new Image::ExifTool object
115  my $exifTool = new Image::ExifTool;
116
117  # Extract meta information from an image
118  $exifTool->ExtractInfo($file, $options);
119
120  # Set a new value for a tag
121  $exifTool->SetNewValue($tag, $newValue);
122
123  # Write new meta information to a file
124  $exifTool->WriteInfo($file);
125
126}
127
128sub _set_current_image_filepaths {
129    my ( $self ) = @_;
130
131    my ( $vol, $dir, $file ) = File::Spec->splitpath(
132        $self->current_image->file
133    );
134
135    my ( $filename, $ext ) = split /\./, $file ;
136
137    $self->current_image->wx_thumb_file( 
138        File::Spec->catfile(
139            $self->wx_thumb_dir,
140            sprintf(
141                "%s.%s",
142                $filename,
143                $self->type,
144            )
145        )
146    );
147
148    $self->current_image->preview_file( 
149        File::Spec->catfile(
150            $self->preview_dir,
151            sprintf(
152                "%s.%s",
153                $filename,
154                $self->type,
155            )
156        )
157    );
158
159
160    $self->current_image->site_thumb_file( 
161        File::Spec->catfile(
162            $self->site_thumb_dir,
163            sprintf(
164                "%s.%s",
165                $filename,
166                $self->type,
167            )
168        )
169    );
170
171       
172}
173
174sub SetCurrentImage {
175    my ( $self, $indx ) = @_;   
176
177    $self->current_image(
178        $self->images->[$indx]
179    );
180}
181
182
183sub SetNewFiles {
184    my ( $self, $files ) = @_;
185
186    $self->new_files( $files );
187
188    # if some files have been previously selected
189    my $i = scalar @{$self->images};
190    my $count = 0;
191    $self->count($count);
192    my $errors = 0;
193    map {
194        # read exif metadata
195        my $info;
196
197
198        eval {
199            $info = ImageInfo( $_ );
200        };
201
202        $info = {} if($@);
203
204        $self->_add_image($_, $info, $i);       
205        $self->SetCurrentImage($i);
206        $self->_set_current_image_filepaths();
207
208        my $create_gui_preview;
209        if($self->use_exif_preview){       
210            # an exif preview is available. we try to use it
211            if(defined $info->{PreviewImage} ){
212                printf("use preview\n");
213                $self->_write_preview_image( $info->{PreviewImage} );
214                my $image = new Image::Magick;
215                eval {
216                        $create_gui_preview = $image->ReadImage(
217                        $self->current_image->preview_file
218                    );
219                };
220                unlink $self->current_image->preview_file if $create_gui_preview;
221            }
222            else {
223                $create_gui_preview = 1;
224            }
225        }
226        else {
227            $create_gui_preview = 1;
228        }
229        print "create gui preview", $create_gui_preview, "\n";
230        # have to create a preview file
231        if($create_gui_preview) {
232            eval {
233                if(!$self->CreateGUIPreview()){
234                    # use method provided by the caller
235                    # source, target, type, ratio
236                    $self->ResizeCallback->(
237                        $self->current_image->file,
238                        $self->current_image->preview_file,
239                        $self->type,
240                        $self->preview_ratio,
241                        undef,
242                        undef,
243                        $self->quality,
244                    );
245                }
246            };# create a preview file
247        }   
248
249        $self->RotateImage(
250            $self->current_image->preview_file,
251        ) if $self->auto_rotate;
252
253        $self->_set_exif_tag(
254            $self->current_image->preview_file,
255            'Orientation',
256            'Horizontal (normal)',
257        ) if $self->auto_rotate;
258
259
260        # Now, we should have a valid preview image.
261        # try to thumbnail it
262        eval {
263            printf("create gui thumbnail\n");
264            # use the preview image to create a gui display thumbnail
265            $self->CreateGUIThumbnail();
266        };
267        # ok
268        if(!$@){
269            $self->progress_msg("Thumbnail and preview created for %s");
270            $i++;
271            $count++;
272            $self->count($count);
273        }
274        else {
275            $self->progress_msg("An error has occured when processing %s\n$@");
276            # remove from list
277            splice @{$self->images}, $i, 1;
278            $errors++;
279        }
280       
281        $self->SetNewFilesProgressCallback->();
282        $self->SetNewFilesViewerRefreshCallback->();
283
284    }
285    @{$files};
286    $self->SetNewFilesDisplayEndInfoCallback->(
287        sprintf(
288            "%s images added to the selection\n\n%s errors",
289            $self->count,
290            $errors
291           
292        )
293    );
294   
295    $self->Store;
296   
297}
298
299# key is file path
300sub _add_image {
301    my ( $self, $file, $info, $i ) = @_;       
302
303    my $image = Uploader::Image->new(
304        {
305            file              => $_,
306            site_name         => sprintf(
307                                     "%s %s", 
308                                     $self->default_name_prefix, 
309                                     $i,
310                                 ),
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    => $_,
317        }
318    );
319
320    # append to image list
321    $self->images->[$i] = $image ;
322
323}
324
325
326sub RemoveImageSelection {
327    my ( $self ) = @_;
328   
329    return if (! scalar @{$self->images} );
330    return if (! defined $self->image_selection );
331   
332    # higher first, to keep same indexes during remove
333    my @images = reverse @{$self->image_selection};     
334    map {
335        my $image = $self->images->[$_]->file;
336        splice @{$self->images}, $_, 1 ;
337        $self->wx_thumb_imglist->Remove($_);
338        shift @images;
339    }
340    @images;
341   
342    # clear image selection
343    $self->image_selection([]);
344}
345
346# used for display in GUI. has to fit a square box ( wxImageList )
347sub CreateGUIThumbnail {
348    my ( $self ) = @_;
349
350    return 1 if( -e $self->current_image->wx_thumb_file );
351    my $rval = 0;
352print "CreateGUIThumbnail ", $self->current_image->wx_thumb_file, "\n";
353    my $image = new Image::Magick;
354
355    my $size = $self->wx_thumb_size;
356
357    my $status = $image->Set(size=>sprintf("%sx%s", 3*$size, 3*$size));
358    warn "$status" if $status ;
359
360    $status = $image->ReadImage(
361        $self->current_image->preview_file
362    );
363    warn "$status" if $status;
364    return $rval if $status;
365
366    $self->current_image->preview_w(
367        $image->Get('width')
368    );
369    $self->current_image->preview_h(
370        $image->Get('height')
371    );
372
373
374    $status = $image->Thumbnail(
375        geometry=>sprintf("%s%s>", $size*$size, '@')
376    );
377    warn "$status" if $status;
378    return $rval if $status;
379
380    $status = $image->Set(background=>"white");
381    warn "$status" if $status ;
382
383    $status = $image->Set(Gravity=>"Center");
384    warn "$status" if $status ;
385
386    $image->Extent(
387        geometry=>sprintf("%sx%s", $size, $size),
388        gravity=>'center',
389    );
390
391    $image->Set(
392        quality=>$self->wx_quality
393    );
394
395    $status = $image->Strip();
396    warn "$status" if $status ;
397   
398
399    $image->Write(
400        sprintf(
401            "%s:%s",
402            $self->type,
403            $self->current_image->wx_thumb_file,
404        )
405    );
406
407    undef $image;
408   
409    $rval = 1;
410   
411    return $rval;
412}
413
414
415sub CreateGUIPreview {
416    my ( $self ) = @_;
417    printf("CreateGUIPreview %s\n", $self->current_image->preview_file );
418    return 1 if( -e $self->current_image->preview_file );
419   
420    my $rval = 1;
421
422    my $image = Image::Magick->new();
423
424    my $ratio = $self->preview_ratio;
425
426
427    my $status = $image->Read(
428        sprintf(
429            "%s",
430            $self->current_image->file,
431        )
432    );
433    warn "$status ", $self->current_image->file, "\n" if $status ;
434    return 0 if $status;
435
436    $status = $image->Thumbnail(
437        geometry=>sprintf(
438                              "%s%%x%s%%>", 
439                              $ratio, 
440                              $ratio
441                         )
442    );
443    warn "$status" if $status ;
444    return 0 if $status;
445
446
447    $status = $image->Set(background=>"white");
448    warn "$status" if $status ;
449
450    $status = $image->Set(Gravity=>"Center");
451    warn "$status" if $status ;
452
453
454    $image->Set(quality=>$self->wx_quality);
455
456
457    $status = $image->Write(
458        sprintf(
459            "%s:%s",
460            $self->type,
461            $self->current_image->preview_file,
462        )
463    );
464    warn "$status" if $status ;
465    return 0 if $status;
466   
467    undef $image;
468
469    return $rval;
470}
471
472
473sub CreateResized {
474    my ( $self ) = @_;
475   
476    my $rval = 1 ;
477    return $rval if( -e $self->current_image->site_resized_file );
478
479    printf(
480        "Create resized %s\n",
481        $self->current_image->file,
482    );     
483
484    my $image = new Image::Magick;
485
486    my $status = $image->ReadImage(
487        $self->current_image->file
488    );
489    warn "$status" if $status ;
490    return 0 if $status;
491
492    my $w = $image->Get('width');
493    my $h = $image->Get('height');
494       
495    # should calculate the aspect ratio
496    my $resize_w = $self->resize_w;
497    my $resize_h = $self->resize_h;
498       
499    if( $w < $h ){
500        my $resize_w_ = $resize_w;
501        $resize_w = $resize_h;
502        $resize_h = $resize_w_;
503    }
504   
505    $status = $image->Resize(
506        geometry => sprintf("%sx%s>", $resize_w, $resize_h), 
507        filter => sprintf("%s", $self->filter), 
508        blur => $self->blur
509    );
510    warn "$status" if $status ;
511    return 0 if $status;
512
513    $status = $image->Set(Gravity=>"Center");
514    warn "$status" if $status ;
515
516    # exif from original image
517    my $orientation = $self->current_image->exif_metadata->{Orientation};
518   
519    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
520    if( $orientation =~ m/Rotate (\d+)/ ){
521        printf(
522            "Rotate %s\n",
523            $1
524        );
525   
526        $image->Rotate( degrees=>$1 ); 
527    }
528
529    $status = $image->Set(quality=>$self->quality);
530    warn "$status" if $status ;
531
532    $status = $image->Set(interlace=>$self->interlace);
533    warn "$status" if $status ;
534
535    $image->Write(
536        sprintf(
537            "%s:%s",
538            $self->type,
539            $self->current_image->site_resized_file,
540        )
541    );
542    warn "$status" if $status ;
543    return 0 if $status;
544   
545    undef $image;
546
547   
548    $rval = 0 if $status;
549
550    return $rval;
551}
552
553sub CreateThumbnail {
554    my ( $self ) = @_;
555   
556    return 1 if( -e $self->current_image->site_thumb_file );
557   
558    my $rval = 1;
559
560    my $image = new Image::Magick;
561
562    my $status = $image->ReadImage(
563        $self->current_image->site_resized_file
564    );
565    warn "$status" if $status ;
566
567   
568    $status = $image->Resize(
569        geometry => sprintf(
570                                "%sx%s>", 
571                                $self->thumb_size, 
572                                $self->thumb_size
573                           ),
574    );
575    warn "$status" if $status ;
576
577    $status = $image->Set(Gravity=>"Center");
578    warn "$status" if $status ;
579
580    $status = $image->Set(quality=>$self->th_quality);
581    warn "$status" if $status ;
582
583    $status = $image->Strip();
584    warn "$status" if $status ;
585
586
587    $image->Write(
588        sprintf(
589            "%s:%s",
590            $self->type,
591            $self->current_image->site_thumb_file,
592        )
593    );
594   
595    undef $image;
596
597
598    $rval = 0 if $status;
599
600    return $rval;
601}
602
603
604
605sub _select_exif_data {
606    my ( $self, $exif ) = @_;
607
608    return {
609        map {
610            $_ => $exif->{$_},
611        }
612        qw/
613            CreateDate
614            ImageWidth
615            ImageHeight
616            Orientation
617            DateTimeOriginal
618            ISO
619            ExposureTime
620            ApertureValue
621            FocalLength
622            Lens
623            Exposure
624            Make
625            Model
626        /
627    };   
628}
629
630sub Store {
631    my ( $self ) = @_;
632   
633    my $data = $self->get_storable(
634        [ 
635            qw/
636                images
637                thumb_size
638                preview_ratio
639                type
640                filter
641                blur
642                quality
643                wx_quality
644                th_quality
645                prefix
646                author
647                count
648                resize_w
649                resize_h
650                new_files
651                storable_file
652                wx_thumb_size
653                current_image
654                images
655                exif_metadata
656                wx_thumb_dir
657                preview_dir
658                site_resized_dir
659                site_thumb_dir
660                userdata_dir
661                progress_msg
662                default_name_prefix
663                upload_high
664                auto_rotate
665                interlace
666                create_resized
667                use_exif_preview
668            /
669        ] 
670   
671    );
672    eval {
673        store $data, $self->storable_file;
674    };
675    if($@){
676        print $@, "\n"; 
677    }
678}
679
680
681
682sub UploadSelection {
683    my ( $self ) = @_; 
684
685    my $viewer_callback = $self->UploadImagesViewerCallback ;
686
687
688    $self->upload_rejects(
689        []
690    );
691
692    my $count = 1;
693    my $msg;
694    $self->count(
695        $count
696    );
697    my $uploaded = 0;
698    my $rejected = 0;
699    my $time_begin = time;
700    my $last_error;
701    map {
702        # current image object         
703        $self->current_image(
704            $self->images->[$_]
705        );
706
707        my ( $vol, $dir, $file ) = File::Spec->splitpath(
708            $self->current_image->file
709        );
710       
711        my $site_name = $self->current_image->site_name;
712   
713        my ( $filename, $ext ) = split /\./, $file ;
714
715        # lately defined to make sure we have the last global properties ( resize_w, resize_h )
716        $self->current_image->site_resized_file( 
717            File::Spec->catfile(
718                $self->site_resized_dir,
719                sprintf(
720                    "%s_%sx%s.%s",
721                    $filename,
722                    $self->resize_w,
723                    $self->resize_h,
724                    $self->type,
725                )
726            )
727        );
728       
729        $msg = sprintf(
730            "Preparing resized image for %s - %s",
731            $site_name,
732            $file,
733        ); 
734
735        eval {
736            # set current image thumbnail
737            $self->progress_thumbnail_refresh->();
738
739            $self->progress_msg_refresh->($msg);
740   
741            # update upload progress dialog
742            $self->progressbar_refresh->(0.25);
743        };
744        # user cancelled : dialog box is destroyed
745        croak "Upload cancelled." if $@ ;
746
747        if( $self->create_resized ){
748            eval {
749                if(!$self->CreateResized()){
750                    printf("CreateResized failed %s. Use ResizeCallback\n", $@);
751                    # use method provided by the caller
752                    # source, target, type, ratio, width, $height
753                    $self->ResizeCallback->(
754                        $self->current_image->file,
755                        $self->current_image->site_resized_file,
756                        $self->type,
757                        undef,
758                        $self->resize_w,
759                        $self->resize_h,
760                        $self->quality,
761                    );
762               
763                    $self->RotateImage(
764                        $self->current_image->site_resized_file,
765                    ) if $self->auto_rotate;
766                }
767            };
768            $self->_set_exif_tag(
769                $self->current_image->site_resized_file,
770                'Orientation',
771                'Horizontal (normal)',
772            ) if $self->auto_rotate;
773        }
774        # the original is at the right size, no need to create a resize
775        else {
776            $self->current_image->site_resized_file(
777                $self->current_image->file,
778            );
779        }
780
781
782
783        # if upload high, rotate a copy of original file
784        if($self->upload_high){
785            $self->CreateHigh();
786        }
787
788        $msg = sprintf(
789            "Preparing thumbnail for %s - %s",
790            $site_name,
791            $file,
792        );
793
794        eval {
795            $self->progress_msg_refresh->($msg);
796        };
797        croak "Upload cancelled." if $@ ;
798
799        eval {
800            $self->CreateThumbnail();
801        };
802
803        if($@){
804            $msg = sprintf(
805                "An error has occured %s - %s\n$@",
806                $site_name,
807                $file
808            );
809        }
810        else{
811            $msg = sprintf(
812                "Uploading %s - %s",
813                $site_name,
814                $file
815            );
816        }
817        eval {
818            $self->progress_msg_refresh->($msg);
819            $self->progressbar_refresh->(0.50);
820        };
821        croak "Upload cancelled." if $@ ;
822
823        # photo metadata
824        $self->_prepare_upload_properties();           
825        my ( $status, $status_msg ) = $self->pwg->UploadImage();
826
827        if ( $status ){
828            $msg = sprintf(
829                "%s : %s upload succcessful.",
830                $site_name,
831                $file
832            );
833            $uploaded++;
834        } else {
835            $msg = sprintf(
836                "An error has occured.\n%s : %s upload is cancelled.\n$status_msg",
837                $site_name,
838                $file
839            );
840            $rejected++;
841            $last_error = $status_msg;
842        }       
843       
844        $count++;
845        $self->count(
846            $count
847        );
848        # update upload progress dialog
849        eval {
850            $self->progress_msg_refresh->($msg);
851            $self->progressbar_refresh->(1);
852        };
853        croak "Upload cancelled." if $@ ;
854       
855    }
856    @{$self->image_selection} if defined 
857        $self->image_selection;
858
859    my $time_end = time;
860    my $duration = $time_end - $time_begin;
861    $msg = sprintf(
862        "%s images processed\n\n%s images uploaded\n\n%s images in errors and not uploaded - $last_error\n\nDuration : %s seconds",
863        $self->count - 1,
864        $uploaded,
865        $rejected,
866        $duration,
867    );
868    $self->progress_endinfo_refresh->($msg);
869}
870
871# if we need to rotate
872sub CreateHigh {
873    my ( $self ) = @_;
874
875    my $orientation = $self->current_image->exif_metadata->{Orientation};
876   
877    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
878    if( $self->auto_rotate and $orientation =~ m/Rotate (\d+)/ ){
879
880        my ( $vol, $dir, $file ) = File::Spec->splitpath(
881            $self->current_image->file
882        );
883   
884        my ( $filename, $ext ) = split /\./, $file ;
885   
886        # high_file is a copy of original
887        $self->current_image->site_high_file( 
888            File::Spec->catfile(
889                $self->site_resized_dir,
890                sprintf(
891                    "%s_high.%s",
892                    $filename,
893                    $self->type,
894                )
895            )
896        );
897
898        my $image = Image::Magick->new();
899        # we read original
900        my $status = $image->Read(
901            $self->current_image->file
902        );
903        warn "$status ", $self->current_image->file, "\n" if $status ;
904        return 0 if $status;
905
906        $image->Rotate( degrees=>$1 ); 
907       
908        $image->Write(
909            filename=>$self->current_image->site_high_file
910        );
911        warn "$status ", $self->current_image->site_high_file, "\n" if $status ;
912        return 0 if $status;
913       
914        undef $image;
915
916        $self->_set_exif_tag(
917            $self->current_image->site_high_file,
918            'Orientation',
919            'Horizontal (normal)',
920        );
921
922        # Now all images that need to be rotated are done. Update exif
923        $self->current_image->exif_metadata->{Orientation} = 'Horizontal (normal)';
924    }
925    else{
926        # high file is the original file
927        $self->current_image->site_high_file(
928            $self->current_image->file
929        );
930    }
931
932    return 1;
933}
934
935sub _prepare_upload_properties {
936    my ( $self ) = @_;
937   
938    $self->pwg->upload_high(
939        $self->upload_high
940    );
941
942    $self->pwg->site_high_file(
943        $self->current_image->site_high_file
944    );
945
946    $self->pwg->site_resized_file(
947        $self->current_image->site_resized_file
948    );
949
950    $self->pwg->site_thumb_file(
951        $self->current_image->site_thumb_file
952    );
953
954    $self->pwg->site_author(
955        $self->current_image->site_author
956    );
957
958    $self->pwg->site_comment(
959        $self->current_image->site_comment
960    );
961
962    $self->pwg->site_image_name(
963        $self->current_image->site_name
964    );
965
966    $self->pwg->site_img_date_creation(
967        $self->current_image->create_date
968    );
969
970    $self->current_image->site_categories(
971        $self->categories
972    );
973
974    $self->pwg->categories(
975        sprintf(
976            "%s",
977            join(';', @{$self->categories})
978        )
979    );
980
981    $self->pwg->tags(
982        #join(',', @{$self->current_image->site_tags})
983    );
984       
985}
986
987# read Orientation exif tag from original image
988# apply rotation to image ( preview or resize )
989sub RotateImage {
990    my ( $self, $file ) = @_;
991   
992    # exif from original image
993    my $orientation = $self->current_image->exif_metadata->{Orientation};
994   
995    # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
996    if( $orientation =~ m/Rotate (\d+)/ ){
997        printf(
998            "Rotate %s\n",
999            $1
1000        );
1001
1002        my $image = Image::Magick->new();
1003       
1004        # read resized file
1005        my $status = $image->Read(
1006            $file
1007        );
1008        warn "$status ", $file, "\n" if $status ;
1009        return 0 if $status;
1010   
1011        $image->Rotate( degrees=>$1 ); 
1012       
1013        # write resizd file
1014        $image->Write(
1015            filename=>$file
1016        );
1017        warn "$status ", $file, "\n" if $status ;
1018        return 0 if $status;
1019       
1020        undef $image;
1021   
1022    }   
1023    return 1;
1024}
1025
10261;
Note: See TracBrowser for help on using the repository browser.