Fixes GDImageAdapter::resize/clip
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / image / adapter / GDImageAdapter.class.php
CommitLineData
b86ca09c 1<?php
64a820cf 2namespace wcf\system\image\adapter;
a3399fc5 3use wcf\system\exception\SystemException;
a17de04e 4use 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 */
16class 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 -> &#65;
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}