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