Auftrags-Controller: Workflow -> Rechnung (Speichern und Rechnung erfassen)
[kivitendo-erp.git] / SL / Controller / Helper / ThumbnailCreator.pm
1 package SL::Controller::Helper::ThumbnailCreator;
2
3 use strict;
4
5 use SL::Locale::String qw(t8);
6 use Carp;
7 use GD;
8 use Image::Info;
9 use File::MimeInfo::Magic;
10 use List::MoreUtils qw(apply);
11 use List::Util qw(max);
12 use Rose::DB::Object::Util;
13
14 require Exporter;
15 our @ISA      = qw(Exporter);
16 our @EXPORT   = qw(file_create_thumbnail file_update_thumbnail file_probe_type file_probe_image_type file_update_type_and_dimensions);
17
18 our %supported_mime_types = (
19   'image/gif'  => { extension => 'gif', convert_to_png => 1, },
20   'image/png'  => { extension => 'png' },
21   'image/jpeg' => { extension => 'jpg' },
22   'image/tiff' => { extension => 'tif'},
23 );
24
25 sub file_create_thumbnail {
26   my ($thumb) = @_;
27   croak "No picture set yet" if !$thumb->{content};
28   my $image            = GD::Image->new($thumb->{content});
29   my ($width, $height) = $image->getBounds;
30   my $max_dim          = 64;
31   my $curr_max         = max $width, $height, 1;
32   my $factor           = $curr_max <= $max_dim ? 1 : $curr_max / $max_dim;
33   my $new_width        = int($width  / $factor + 0.5);
34   my $new_height       = int($height / $factor + 0.5);
35   my $thumbnail        = GD::Image->new($new_width, $new_height);
36
37   $thumbnail->copyResized($image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
38
39   $thumb->{thumbnail_img_content} = $thumbnail->png;
40   $thumb->{thumbnail_img_content_type} = "image/png";
41   $thumb->{thumbnail_img_width} = $new_width;
42   $thumb->{thumbnail_img_height} = $new_height;
43   return $thumb;
44
45 }
46
47 sub file_update_thumbnail {
48   my ($self) = @_;
49
50   return 1 if !$self->file_content || !$self->file_content_type || !Rose::DB::Object::Util::get_column_value_modified($self, 'file_content');
51   $self->file_create_thumbnail;
52   return 1;
53 }
54
55 sub file_probe_image_type {
56   my ($self, $mime_type, $basefile) = @_;
57
58   if ( !$supported_mime_types{ $mime_type } ) {
59     $self->js->flash('error',t8('file \'#1\' has unsupported image type \'#2\' (supported types: #3)',
60                                 $basefile, $mime_type, join(' ', sort keys %supported_mime_types)));
61     return 1;
62   }
63   return 0;
64 }
65
66 sub file_probe_type {
67   my ($content) = @_;
68   return (t8("No file uploaded yet")) if !$content;
69   my $info = Image::Info::image_info(\$content);
70   if (!$info || $info->{error} || !$info->{file_media_type} || !$supported_mime_types{ $info->{file_media_type} }) {
71     $::lxdebug->warn("Image::Info error: " . $info->{error}) if $info && $info->{error};
72     return (t8('Unsupported image type (supported types: #1)', join(' ', sort keys %supported_mime_types)));
73   }
74
75   my $thumbnail;
76   $thumbnail->{file_content_type} = $info->{file_media_type};
77   $thumbnail->{file_image_width} = $info->{width};
78   $thumbnail->{file_image_height} = $info->{height};
79   $thumbnail->{content} = $content;
80
81   $thumbnail = &file_create_thumbnail($thumbnail);
82
83   return $thumbnail;
84 }
85
86 sub file_update_type_and_dimensions {
87   my ($self) = @_;
88
89   return () if !$self->file_content;
90   return () if $self->file_content_type && $self->files_img_width && $self->files_img_height && !Rose::DB::Object::Util::get_column_value_modified($self, 'file_content');
91
92   my @errors = $self->file_probe_type;
93   return @errors if @errors;
94
95   my $info = $supported_mime_types{ $self->file_content_type };
96   if ($info->{convert_to_png}) {
97     $self->file_content(GD::Image->new($self->file_content)->png);
98     $self->file_content_type('image/png');
99     $self->filename(apply { s/\.[^\.]+$//;  $_ .= '.png'; } $self->filename);
100   }
101   return ();
102 }
103
104 1;
105 __END__
106
107 =pod
108
109 =encoding utf8
110
111 =head1 NAME
112
113   SL::DB::Helper::ThumbnailCreator - DatabaseClass Helper for Fileuploads
114
115 =head1 SYNOPSIS
116
117   use SL::DB::Helper::ThumbnailCreator;
118
119   # synopsis...
120
121 =head1 DESCRIPTION
122
123   # longer description..
124
125 =head1 AUTHOR
126
127   Werner Hahn E<lt>wh@futureworldsearch.netE<gt>
128
129 =cut
130
131
132 =head1 INTERFACE
133
134
135 =head1 DEPENDENCIES
136
137
138 =head1 SEE ALSO
139
140