1 <?php
2 /**
3 * @author Gasper Kozak
4 * @copyright 2007-2011
5
6 This file is part of WideImage.
7
8 WideImage is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 WideImage is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with WideImage; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
22 * @package Internal/Operations
23 **/
24
25 /**
26 * An Exception for when an invalid fit method is passed
27 *
28 * @package Internal/Operations
29 */
30 class WideImage_Operation_InvalidFitMethodException extends WideImage_Exception {}
31 /**
32 * An Exception for when an invalid resize dimensions are passed
33 *
34 * @package Internal/Operations
35 */
36 class WideImage_Operation_InvalidResizeDimensionException extends WideImage_Exception {}
37
38 /**
39 * Resize operation class
40 *
41 * @package Internal/Operations
42 */
43 class WideImage_Operation_Resize
44 {
45 /**
46 * Prepares and corrects smart coordinates
47 *
48 * @param WideImage_Image $img
49 * @param smart_coordinate $width
50 * @param smart_coordinate $height
51 * @param string $fit
52 * @return array
53 */
54 protected function prepareDimensions($img, $width, $height, $fit)
55 {
56 if ($width === null && $height === null)
57 {
58 $width = $img->getWidth();
59 $height = $img->getHeight();
60 }
61
62 if ($width !== null)
63 $width = WideImage_Coordinate::fix($width, $img->getWidth());
64
65 if ($height !== null)
66 $height = WideImage_Coordinate::fix($height, $img->getHeight());
67
68 if ($width === null)
69 $width = floor($img->getWidth() * $height / $img->getHeight());
70
71 if ($height === null)
72 $height = floor($img->getHeight() * $width / $img->getWidth());
73
74 if ($width === 0 || $height === 0)
75 return array('width' => 0, 'height' => 0);
76
77 if ($fit == null)
78 $fit = 'inside';
79
80 $dim = array();
81 if ($fit == 'fill')
82 {
83 $dim['width'] = $width;
84 $dim['height'] = $height;
85 }
86 elseif ($fit == 'inside' || $fit == 'outside')
87 {
88 $rx = $img->getWidth() / $width;
89 $ry = $img->getHeight() / $height;
90
91 if ($fit == 'inside')
92 $ratio = ($rx > $ry) ? $rx : $ry;
93 else
94 $ratio = ($rx < $ry) ? $rx : $ry;
95
96 $dim['width'] = round($img->getWidth() / $ratio);
97 $dim['height'] = round($img->getHeight() / $ratio);
98 }
99 else
100 throw new WideImage_Operation_InvalidFitMethodException("{$fit} is not a valid resize-fit method.");
101
102 return $dim;
103 }
104
105 /**
106 * Returns a resized image
107 *
108 * @param WideImage_Image $img
109 * @param smart_coordinate $width
110 * @param smart_coordinate $height
111 * @param string $fit
112 * @param string $scale
113 * @return WideImage_Image
114 */
115 function execute($img, $width, $height, $fit, $scale)
116 {
117 $dim = $this->prepareDimensions($img, $width, $height, $fit);
118 if (($scale === 'down' && ($dim['width'] >= $img->getWidth() && $dim['height'] >= $img->getHeight())) ||
119 ($scale === 'up' && ($dim['width'] <= $img->getWidth() && $dim['height'] <= $img->getHeight())))
120 $dim = array('width' => $img->getWidth(), 'height' => $img->getHeight());
121
122 if ($dim['width'] <= 0 || $dim['height'] <= 0)
123 throw new WideImage_Operation_InvalidResizeDimensionException("Both dimensions must be larger than 0.");
124
125 if ($img->isTransparent() || $img instanceof WideImage_PaletteImage)
126 {
127 $new = WideImage_PaletteImage::create($dim['width'], $dim['height']);
128 $new->copyTransparencyFrom($img);
129 if (!imagecopyresized(
130 $new->getHandle(),
131 $img->getHandle(),
132 0, 0, 0, 0,
133 $new->getWidth(),
134 $new->getHeight(),
135 $img->getWidth(),
136 $img->getHeight()))
137 throw new WideImage_GDFunctionResultException("imagecopyresized() returned false");
138 }
139 else
140 {
141 $new = WideImage_TrueColorImage::create($dim['width'], $dim['height']);
142 $new->alphaBlending(false);
143 $new->saveAlpha(true);
144 if (!imagecopyresampled(
145 $new->getHandle(),
146 $img->getHandle(),
147 0, 0, 0, 0,
148 $new->getWidth(),
149 $new->getHeight(),
150 $img->getWidth(),
151 $img->getHeight()))
152 throw new WideImage_GDFunctionResultException("imagecopyresampled() returned false");
153 $new->alphaBlending(true);
154 }
155 return $new;
156 }
157 }
158