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