Commit | Line | Data |
---|---|---|
b86ca09c | 1 | <?php |
64a820cf | 2 | namespace wcf\system\image\adapter; |
a3399fc5 | 3 | use wcf\system\exception\SystemException; |
a17de04e | 4 | use wcf\util\StringUtil; |
64a820cf AE |
5 | |
6 | /** | |
7 | * Image adapter for bundled GD imaging library. | |
8 | * | |
9f959ced MS |
9 | * @author Alexander Ebert |
10 | * @copyright 2001-2012 WoltLab GmbH | |
64a820cf AE |
11 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
12 | * @package com.woltlab.wcf | |
13 | * @subpackage system.image.adapter | |
9f959ced | 14 | * @category Community Framework |
64a820cf AE |
15 | */ |
16 | class GDImageAdapter implements IImageAdapter { | |
17 | /** | |
18 | * active color | |
9f959ced MS |
19 | * @var integer |
20 | */ | |
64a820cf AE |
21 | protected $color = null; |
22 | ||
b86ca09c AE |
23 | /** |
24 | * image height | |
25 | * @var integer | |
a17de04e | 26 | */ |
b86ca09c AE |
27 | protected $height = 0; |
28 | ||
29 | /** | |
30 | * loaded image | |
31 | * @var resource | |
a17de04e | 32 | */ |
b86ca09c AE |
33 | protected $image = null; |
34 | ||
35 | /** | |
36 | * image type | |
37 | * @var integer | |
38 | */ | |
39 | protected $type = 0; | |
40 | ||
41 | /** | |
42 | * image width | |
43 | * @var integer | |
a17de04e | 44 | */ |
b86ca09c AE |
45 | protected $width = 0; |
46 | ||
47 | /** | |
64a820cf | 48 | * @see wcf\system\image\adapter\IImageAdapter::load() |
b86ca09c AE |
49 | */ |
50 | public function load($image, $type = '') { | |
51 | if (!is_resource($image)) { | |
52 | throw new SystemException("Image resource is invalid."); | |
53 | } | |
54 | ||
55 | if (empty($type)) { | |
56 | throw new SystemException("Image type is missing."); | |
57 | } | |
58 | ||
59 | $this->image = $image; | |
60 | $this->type = $type; | |
61 | ||
62 | $this->height = imageSY($this->image); | |
63 | $this->width = imageSX($this->image); | |
64 | } | |
65 | ||
66 | /** | |
64a820cf | 67 | * @see wcf\system\image\adapter\IImageAdapter::loadFile() |
a17de04e | 68 | */ |
b86ca09c AE |
69 | public function loadFile($file) { |
70 | list($this->width, $this->height, $this->type) = getImageSize($file); | |
71 | ||
72 | switch ($this->type) { | |
73 | case IMAGETYPE_GIF: | |
74 | $this->image = imageCreateFromGif($file); | |
75 | break; | |
76 | ||
77 | case IMAGETYPE_JPEG: | |
78 | $this->image = imageCreateFromJpeg($file); | |
79 | break; | |
80 | ||
81 | case IMAGETYPE_PNG: | |
82 | $this->image = imageCreateFromPng($file); | |
83 | break; | |
84 | ||
85 | default: | |
86 | throw new SystemException("Could not read image '".$file."', format is not recognized."); | |
87 | break; | |
88 | } | |
89 | } | |
90 | ||
45140a75 | 91 | /** |
9f959ced | 92 | * @see wcf\system\image\adapter\IImageAdapter::createEmptyImage() |
45140a75 TD |
93 | */ |
94 | public function createEmptyImage($width, $height) { | |
95 | $this->image = imageCreate($width, $height); | |
96 | $this->type = IMAGETYPE_PNG; | |
97 | $this->setColor(0xFF, 0xFF, 0xFF); | |
98 | $this->color = null; | |
99 | } | |
100 | ||
b86ca09c | 101 | /** |
64a820cf | 102 | * @see wcf\system\image\adapter\IImageAdapter::createThumbnail() |
a17de04e | 103 | */ |
b86ca09c | 104 | public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) { |
b86ca09c | 105 | $width = $height = $x = $y = 0; |
32f6cd95 MW |
106 | $sourceWidth = $this->width; |
107 | $sourceHeight = $this->height; | |
b86ca09c AE |
108 | |
109 | if ($obtainDimensions) { | |
a3399fc5 AE |
110 | if ($maxWidth / $this->width < $maxHeight / $this->height) { |
111 | $width = $maxWidth; | |
112 | $height = round($this->height * ($width / $this->width)); | |
b86ca09c AE |
113 | } |
114 | else { | |
a3399fc5 AE |
115 | $height = $maxHeight; |
116 | $width = round($this->width * ($height / $this->height)); | |
b86ca09c AE |
117 | } |
118 | } | |
119 | else { | |
f7ac2ad1 MW |
120 | $width = $maxWidth; |
121 | $height = $maxHeight; | |
a3399fc5 | 122 | |
f7ac2ad1 MW |
123 | if ($maxWidth / $this->width < $maxHeight / $this->height) { |
124 | $cut = (($sourceWidth * ($maxHeight / $this->height)) - $maxWidth) / ($maxHeight / $this->height); | |
125 | $x = ceil($cut / 2); | |
126 | $sourceWidth = $sourceWidth - $x * 2; | |
b86ca09c AE |
127 | } |
128 | else { | |
f7ac2ad1 MW |
129 | $cut = (($sourceHeight * ($maxWidth / $this->width)) - $maxHeight) / ($maxWidth / $this->width); |
130 | $y = ceil($cut / 2); | |
131 | $sourceHeight = $sourceHeight - $y * 2; | |
b86ca09c AE |
132 | } |
133 | } | |
134 | ||
135 | // resize image | |
136 | $image = imageCreateTrueColor($width, $height); | |
137 | imageAlphaBlending($image, false); | |
32f6cd95 | 138 | imageCopyResampled($image, $this->image, 0, 0, $x, $y, $width, $height, $sourceWidth, $sourceHeight); |
b86ca09c AE |
139 | imageSaveAlpha($image, true); |
140 | ||
141 | return $image; | |
142 | } | |
143 | ||
144 | /** | |
64a820cf | 145 | * @see wcf\system\image\adapter\IImageAdapter::clip() |
b86ca09c AE |
146 | */ |
147 | public function clip($originX, $originY, $width, $height) { | |
b86ca09c AE |
148 | $image = imageCreateTrueColor($width, $height); |
149 | imageAlphaBlending($image, false); | |
150 | ||
151 | imageCopy($image, $this->image, 0, 0, $originX, $originY, $width, $height); | |
152 | imageSaveAlpha($image, true); | |
153 | ||
08c8e6f8 MS |
154 | // update image resource to also update width and height |
155 | $this->load($image, $this->type); | |
b86ca09c AE |
156 | } |
157 | ||
158 | /** | |
64a820cf | 159 | * @see wcf\system\image\adapter\IImageAdapter::resize() |
b86ca09c AE |
160 | */ |
161 | public function resize($originX, $originY, $originWidth, $originHeight, $targetX = 0, $targetY = 0, $targetWidth = 0, $targetHeight = 0) { | |
b86ca09c AE |
162 | $image = imageCreateTrueColor($targetWidth, $targetHeight); |
163 | imageAlphaBlending($image, false); | |
164 | ||
165 | imageCopyResampled($image, $this->image, $targetX, $targetY, $originX, $originY, $targetWidth, $targetHeight, $originWidth, $originHeight); | |
166 | imageSaveAlpha($image, true); | |
167 | ||
08c8e6f8 MS |
168 | // update image resource to also update width and height |
169 | $this->load($image, $this->type); | |
b86ca09c AE |
170 | } |
171 | ||
172 | /** | |
64a820cf | 173 | * @see wcf\system\image\adapter\IImageAdapter::drawRectangle() |
b86ca09c | 174 | */ |
64a820cf AE |
175 | public function drawRectangle($startX, $startY, $endX, $endY) { |
176 | imageFilledRectangle($this->image, $startX, $startY, $endX, $endY, $this->color); | |
b86ca09c AE |
177 | } |
178 | ||
179 | /** | |
64a820cf | 180 | * @see wcf\system\image\adapter\IImageAdapter::drawText() |
b86ca09c | 181 | */ |
64a820cf | 182 | public function drawText($string, $x, $y) { |
d3e0ca88 AE |
183 | if (!StringUtil::isUTF8($string)) { |
184 | throw new SystemException("Only UTF-8 encoded text can be written onto images"); // GD is buggy with UTF-8 | |
185 | } | |
186 | ||
187 | // convert UTF-8 characters > 127 to their numeric representation, e.g. A -> A | |
188 | $string = mb_encode_numericentity($string, array(0x0, 0xFFFF, 0, 0xFFF), 'UTF-8'); | |
189 | ||
64a820cf | 190 | imageString($this->image, 3, $x, $y, $string, $this->color); |
b86ca09c AE |
191 | } |
192 | ||
193 | /** | |
64a820cf | 194 | * @see wcf\system\image\adapter\IImageAdapter::setColor() |
d726f13d | 195 | */ |
64a820cf AE |
196 | public function setColor($red, $green, $blue) { |
197 | $this->color = imageColorAllocate($this->image, $red, $green, $blue); | |
b86ca09c AE |
198 | } |
199 | ||
200 | /** | |
64a820cf AE |
201 | * @see wcf\system\image\adapter\IImageAdapter::hasColor() |
202 | */ | |
203 | public function hasColor() { | |
204 | return ($this->color !== null); | |
205 | } | |
206 | ||
207 | /** | |
208 | * @see wcf\system\image\adapter\IImageAdapter::writeImage() | |
209 | */ | |
b86ca09c | 210 | public function writeImage($image, $filename) { |
a3399fc5 AE |
211 | if (!is_resource($image)) { |
212 | throw new SystemException("Given image is not a valid image resource."); | |
213 | } | |
214 | ||
b86ca09c AE |
215 | ob_start(); |
216 | ||
64a820cf | 217 | if ($this->type == IMAGETYPE_GIF) { |
b86ca09c AE |
218 | imageGIF($image); |
219 | } | |
64a820cf | 220 | else if ($this->type == IMAGETYPE_PNG) { |
b86ca09c AE |
221 | imagePNG($image); |
222 | } | |
223 | else if (function_exists('imageJPEG')) { | |
6da905f4 | 224 | imageJPEG($image, null, 90); |
b86ca09c AE |
225 | } |
226 | ||
45140a75 | 227 | $stream = ob_get_contents(); |
b86ca09c AE |
228 | ob_end_clean(); |
229 | ||
45140a75 | 230 | file_put_contents($filename, $stream); |
b86ca09c AE |
231 | } |
232 | ||
a3399fc5 AE |
233 | /** |
234 | * @see wcf\system\image\adapter\IImageAdapter::getWidth() | |
d726f13d | 235 | */ |
a3399fc5 AE |
236 | public function getWidth() { |
237 | return $this->width; | |
238 | } | |
239 | ||
240 | /** | |
241 | * @see wcf\system\image\adapter\IImageAdapter::getHeight() | |
242 | */ | |
243 | public function getHeight() { | |
244 | return $this->height; | |
245 | } | |
246 | ||
b86ca09c | 247 | /** |
64a820cf | 248 | * @see wcf\system\image\adapter\IImageAdapter::getImage() |
b86ca09c AE |
249 | */ |
250 | public function getImage() { | |
251 | return $this->image; | |
252 | } | |
87646f44 AE |
253 | |
254 | /** | |
255 | * @see wcf\system\image\adapter\IImageAdapter::isSupported() | |
d726f13d | 256 | */ |
87646f44 AE |
257 | public static function isSupported() { |
258 | return true; | |
259 | } | |
b86ca09c | 260 | } |