| File: | C4/Images.pm |
| Coverage: | 25.7% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package C4::Images; | |||||
| 2 | ||||||
| 3 | # Copyright (C) 2011 C & P Bibliography Services | |||||
| 4 | # Jared Camins-Esakov <jcamins@cpbibliograpy.com> | |||||
| 5 | # | |||||
| 6 | # This file is part of Koha. | |||||
| 7 | # | |||||
| 8 | # Koha is free software; you can redistribute it and/or modify it under the | |||||
| 9 | # terms of the GNU General Public License as published by the Free Software | |||||
| 10 | # Foundation; either version 2 of the License, or (at your option) any later | |||||
| 11 | # version. | |||||
| 12 | # | |||||
| 13 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| 14 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| 15 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| 16 | # | |||||
| 17 | # You should have received a copy of the GNU General Public License along | |||||
| 18 | # with Koha; if not, write to the Free Software Foundation, Inc., | |||||
| 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |||||
| 20 | ||||||
| 21 | 2 2 2 | 5572 25 61 | use strict; | |||
| 22 | 2 2 2 | 8 3 56 | use warnings; | |||
| 23 | 2 2 2 2 2 2 | 176 148 50 8 2 26 | use 5.010; | |||
| 24 | ||||||
| 25 | 2 2 2 | 9 2 20 | use C4::Context; | |||
| 26 | 2 2 2 | 15780 311842 645 | use GD; | |||
| 27 | ||||||
| 28 | 2 2 2 | 14 3 331 | use vars qw($debug $VERSION @ISA @EXPORT); | |||
| 29 | ||||||
| 30 | BEGIN { | |||||
| 31 | ||||||
| 32 | # set the version for version checking | |||||
| 33 | 2 | 3 | $VERSION = 3.03; | |||
| 34 | 2 | 10 | require Exporter; | |||
| 35 | 2 | 24 | @ISA = qw(Exporter); | |||
| 36 | 2 | 7 | @EXPORT = qw( | |||
| 37 | &PutImage | |||||
| 38 | &RetrieveImage | |||||
| 39 | &ListImagesForBiblio | |||||
| 40 | &DelImage | |||||
| 41 | ); | |||||
| 42 | 2 | 2513 | $debug = $ENV{KOHA_DEBUG} || $ENV{DEBUG} || 0; | |||
| 43 | } | |||||
| 44 | ||||||
| 45 - 51 | =head2 PutImage
PutImage($biblionumber, $srcimage, $replace);
Stores binary image data and thumbnail in database, optionally replacing existing images for the given biblio.
=cut | |||||
| 52 | ||||||
| 53 | sub PutImage { | |||||
| 54 | 0 | my ( $biblionumber, $srcimage, $replace ) = @_; | ||||
| 55 | ||||||
| 56 | 0 | return -1 unless defined($srcimage); | ||||
| 57 | ||||||
| 58 | 0 | if ($replace) { | ||||
| 59 | 0 | foreach ( ListImagesForBiblio($biblionumber) ) { | ||||
| 60 | 0 | DelImage($_); | ||||
| 61 | } | |||||
| 62 | } | |||||
| 63 | ||||||
| 64 | 0 | my $dbh = C4::Context->dbh; | ||||
| 65 | 0 | my $query = | ||||
| 66 | "INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?);"; | |||||
| 67 | 0 | my $sth = $dbh->prepare($query); | ||||
| 68 | ||||||
| 69 | 0 | my $mimetype = 'image/png' | ||||
| 70 | ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless... | |||||
| 71 | ||||||
| 72 | # Check the pixel size of the image we are about to import... | |||||
| 73 | 0 | my $thumbnail = _scale_image( $srcimage, 140, 200 ) | ||||
| 74 | ; # MAX pixel dims are 140 X 200 for thumbnail... | |||||
| 75 | 0 | my $fullsize = _scale_image( $srcimage, 600, 800 ) | ||||
| 76 | ; # MAX pixel dims are 600 X 800 for full-size image... | |||||
| 77 | 0 | $debug and warn "thumbnail is " . length($thumbnail) . " bytes."; | ||||
| 78 | ||||||
| 79 | 0 | $sth->execute( $biblionumber, $mimetype, $fullsize->png(), | ||||
| 80 | $thumbnail->png() ); | |||||
| 81 | 0 | my $dberror = $sth->errstr; | ||||
| 82 | 0 | warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr; | ||||
| 83 | 0 | undef $thumbnail; | ||||
| 84 | 0 | undef $fullsize; | ||||
| 85 | 0 | return $dberror; | ||||
| 86 | } | |||||
| 87 | ||||||
| 88 - 93 | =head2 RetrieveImage
my ($imagedata, $error) = RetrieveImage($imagenumber);
Retrieves the specified image.
=cut | |||||
| 94 | ||||||
| 95 | sub RetrieveImage { | |||||
| 96 | 0 | my ($imagenumber) = @_; | ||||
| 97 | ||||||
| 98 | 0 | my $dbh = C4::Context->dbh; | ||||
| 99 | 0 | my $query = | ||||
| 100 | 'SELECT mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?'; | |||||
| 101 | 0 | my $sth = $dbh->prepare($query); | ||||
| 102 | 0 | $sth->execute($imagenumber); | ||||
| 103 | 0 | my $imagedata = $sth->fetchrow_hashref; | ||||
| 104 | 0 | if ( $sth->err ) { | ||||
| 105 | 0 | warn "Database error!"; | ||||
| 106 | 0 | return undef; | ||||
| 107 | } | |||||
| 108 | else { | |||||
| 109 | 0 | return $imagedata; | ||||
| 110 | } | |||||
| 111 | } | |||||
| 112 | ||||||
| 113 - 118 | =head2 ListImagesForBiblio
my (@images) = ListImagesForBiblio($biblionumber);
Gets a list of all images associated with a particular biblio.
=cut | |||||
| 119 | ||||||
| 120 | sub ListImagesForBiblio { | |||||
| 121 | 0 | my ($biblionumber) = @_; | ||||
| 122 | ||||||
| 123 | 0 | my @imagenumbers; | ||||
| 124 | 0 | my $dbh = C4::Context->dbh; | ||||
| 125 | 0 | my $query = 'SELECT imagenumber FROM biblioimages WHERE biblionumber = ?'; | ||||
| 126 | 0 | my $sth = $dbh->prepare($query); | ||||
| 127 | 0 | $sth->execute($biblionumber); | ||||
| 128 | 0 | warn "Database error!" if $sth->errstr; | ||||
| 129 | 0 | if ( !$sth->errstr && $sth->rows > 0 ) { | ||||
| 130 | 0 | while ( my $row = $sth->fetchrow_hashref ) { | ||||
| 131 | 0 | push @imagenumbers, $row->{'imagenumber'}; | ||||
| 132 | } | |||||
| 133 | 0 | return @imagenumbers; | ||||
| 134 | } | |||||
| 135 | else { | |||||
| 136 | 0 | return undef; | ||||
| 137 | } | |||||
| 138 | } | |||||
| 139 | ||||||
| 140 - 146 | =head2 DelImage
my ($dberror) = DelImage($imagenumber);
Removes the image with the supplied imagenumber.
=cut | |||||
| 147 | ||||||
| 148 | sub DelImage { | |||||
| 149 | 0 | my ($imagenumber) = @_; | ||||
| 150 | 0 | warn "Imagenumber passed to DelImage is $imagenumber" if $debug; | ||||
| 151 | 0 | my $dbh = C4::Context->dbh; | ||||
| 152 | 0 | my $query = "DELETE FROM biblioimages WHERE imagenumber = ?;"; | ||||
| 153 | 0 | my $sth = $dbh->prepare($query); | ||||
| 154 | 0 | $sth->execute($imagenumber); | ||||
| 155 | 0 | my $dberror = $sth->errstr; | ||||
| 156 | 0 | warn "Database error!" if $sth->errstr; | ||||
| 157 | 0 | return $dberror; | ||||
| 158 | } | |||||
| 159 | ||||||
| 160 | sub _scale_image { | |||||
| 161 | 0 | my ( $image, $maxwidth, $maxheight ) = @_; | ||||
| 162 | 0 | my ( $width, $height ) = $image->getBounds(); | ||||
| 163 | 0 | $debug and warn "image is $width pix X $height pix."; | ||||
| 164 | 0 | if ( $width > $maxwidth || $height > $maxheight ) { | ||||
| 165 | ||||||
| 166 | # $debug and warn "$filename exceeds the maximum pixel dimensions of $maxwidth X $maxheight. Resizing..."; | |||||
| 167 | 0 | my $percent_reduce; # Percent we will reduce the image dimensions by... | ||||
| 168 | 0 | if ( $width > $maxwidth ) { | ||||
| 169 | 0 | $percent_reduce = | ||||
| 170 | sprintf( "%.5f", ( $maxwidth / $width ) ) | |||||
| 171 | ; # If the width is oversize, scale based on width overage... | |||||
| 172 | } | |||||
| 173 | else { | |||||
| 174 | 0 | $percent_reduce = | ||||
| 175 | sprintf( "%.5f", ( $maxheight / $height ) ) | |||||
| 176 | ; # otherwise scale based on height overage. | |||||
| 177 | } | |||||
| 178 | 0 | my $width_reduce = sprintf( "%.0f", ( $width * $percent_reduce ) ); | ||||
| 179 | 0 | my $height_reduce = sprintf( "%.0f", ( $height * $percent_reduce ) ); | ||||
| 180 | 0 | $debug | ||||
| 181 | and warn "Reducing image by " | |||||
| 182 | . ( $percent_reduce * 100 ) | |||||
| 183 | . "\% or to $width_reduce pix X $height_reduce pix"; | |||||
| 184 | 0 | my $newimage = GD::Image->new( $width_reduce, $height_reduce, 1 ) | ||||
| 185 | ; #'1' creates true color image... | |||||
| 186 | 0 | $newimage->copyResampled( $image, 0, 0, 0, 0, $width_reduce, | ||||
| 187 | $height_reduce, $width, $height ); | |||||
| 188 | 0 | return $newimage; | ||||
| 189 | } | |||||
| 190 | else { | |||||
| 191 | 0 | return $image; | ||||
| 192 | } | |||||
| 193 | } | |||||
| 194 | ||||||
| 195 | 1; | |||||