Bug 22688: Unit tests
[koha.git] / C4 / Images.pm
blob856e894d8a6b773bb61278a7dd717239723475d3
1 package C4::Images;
3 # Copyright (C) 2011 C & P Bibliography Services
4 # Jared Camins-Esakov <jcamins@cpbibliograpy.com>
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
21 use strict;
22 use warnings;
23 use 5.010;
25 use C4::Context;
26 use GD;
28 use vars qw($debug $noimage @ISA @EXPORT);
30 BEGIN {
32 require Exporter;
33 @ISA = qw(Exporter);
34 @EXPORT = qw(
35 &PutImage
36 &RetrieveImage
37 &ListImagesForBiblio
38 &DelImage
40 $debug = $ENV{KOHA_DEBUG} || $ENV{DEBUG} || 0;
42 $noimage = pack( "H*",
43 '47494638396101000100800000FFFFFF'
44 . '00000021F90401000000002C00000000'
45 . '010001000002024401003B' );
48 =head2 PutImage
50 PutImage($biblionumber, $srcimage, $replace);
52 Stores binary image data and thumbnail in database, optionally replacing existing images for the given biblio.
54 =cut
56 sub PutImage {
57 my ( $biblionumber, $srcimage, $replace ) = @_;
59 return -1 unless defined($srcimage);
61 if ($replace) {
62 foreach ( ListImagesForBiblio($biblionumber) ) {
63 DelImage($_);
67 my $dbh = C4::Context->dbh;
68 my $query =
69 "INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?);";
70 my $sth = $dbh->prepare($query);
72 my $mimetype = 'image/png'
73 ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless...
75 # Check the pixel size of the image we are about to import...
76 my $thumbnail = _scale_image( $srcimage, 140, 200 )
77 ; # MAX pixel dims are 140 X 200 for thumbnail...
78 my $fullsize = _scale_image( $srcimage, 600, 800 )
79 ; # MAX pixel dims are 600 X 800 for full-size image...
80 $debug and warn "thumbnail is " . length($thumbnail) . " bytes.";
82 $sth->execute( $biblionumber, $mimetype, $fullsize->png(),
83 $thumbnail->png() );
84 my $dberror = $sth->errstr;
85 warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr;
86 undef $thumbnail;
87 undef $fullsize;
88 return $dberror;
91 =head2 RetrieveImage
92 my ($imagedata, $error) = RetrieveImage($imagenumber);
94 Retrieves the specified image.
96 =cut
98 sub RetrieveImage {
99 my ($imagenumber) = @_;
101 my $dbh = C4::Context->dbh;
102 my $query =
103 'SELECT imagenumber, mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?';
104 my $sth = $dbh->prepare($query);
105 $sth->execute($imagenumber);
106 my $imagedata = $sth->fetchrow_hashref;
107 if ( !$imagedata ) {
108 $imagedata->{'thumbnail'} = $noimage;
109 $imagedata->{'imagefile'} = $noimage;
111 if ( $sth->err ) {
112 warn "Database error!" if $debug;
114 return $imagedata;
117 =head2 ListImagesForBiblio
118 my (@images) = ListImagesForBiblio($biblionumber);
120 Gets a list of all images associated with a particular biblio.
122 =cut
124 sub ListImagesForBiblio {
125 my ($biblionumber) = @_;
127 my @imagenumbers;
128 my $dbh = C4::Context->dbh;
129 my $query = 'SELECT imagenumber FROM biblioimages WHERE biblionumber = ?';
130 my $sth = $dbh->prepare($query);
131 $sth->execute($biblionumber);
132 while ( my $row = $sth->fetchrow_hashref ) {
133 push @imagenumbers, $row->{'imagenumber'};
135 return @imagenumbers;
138 =head2 DelImage
140 my ($dberror) = DelImage($imagenumber);
142 Removes the image with the supplied imagenumber.
144 =cut
146 sub DelImage {
147 my ($imagenumber) = @_;
148 warn "Imagenumber passed to DelImage is $imagenumber" if $debug;
149 my $dbh = C4::Context->dbh;
150 my $query = "DELETE FROM biblioimages WHERE imagenumber = ?;";
151 my $sth = $dbh->prepare($query);
152 $sth->execute($imagenumber);
153 my $dberror = $sth->errstr;
154 warn "Database error!" if $sth->errstr;
155 return $dberror;
158 sub _scale_image {
159 my ( $image, $maxwidth, $maxheight ) = @_;
160 my ( $width, $height ) = $image->getBounds();
161 $debug and warn "image is $width pix X $height pix.";
162 if ( $width > $maxwidth || $height > $maxheight ) {
164 # $debug and warn "$filename exceeds the maximum pixel dimensions of $maxwidth X $maxheight. Resizing...";
165 my $percent_reduce; # Percent we will reduce the image dimensions by...
166 if ( $width > $maxwidth ) {
167 $percent_reduce =
168 sprintf( "%.5f", ( $maxwidth / $width ) )
169 ; # If the width is oversize, scale based on width overage...
171 else {
172 $percent_reduce =
173 sprintf( "%.5f", ( $maxheight / $height ) )
174 ; # otherwise scale based on height overage.
176 my $width_reduce = sprintf( "%.0f", ( $width * $percent_reduce ) );
177 my $height_reduce = sprintf( "%.0f", ( $height * $percent_reduce ) );
178 $debug
179 and warn "Reducing image by "
180 . ( $percent_reduce * 100 )
181 . "\% or to $width_reduce pix X $height_reduce pix";
182 my $newimage = GD::Image->new( $width_reduce, $height_reduce, $image->trueColor )
183 ; # if third is set, creates true color image
184 $newimage->copyResampled( $image, 0, 0, 0, 0, $width_reduce,
185 $height_reduce, $width, $height );
186 return $newimage;
188 else {
189 return $image;
193 =head2 NoImage
195 C4::Images->NoImage;
197 Returns the gif to be used when there is no image matching the request, and
198 its mimetype (image/gif).
200 =cut
202 sub NoImage {
203 return $noimage, 'image/gif';