Skip to content

Commit 6b00e12

Browse files
committed
Releasing 1.1.6
2 parents 847f5c6 + 00571fe commit 6b00e12

File tree

1 file changed

+202
-53
lines changed

1 file changed

+202
-53
lines changed

src/TgUtils/ImageUtils.php

Lines changed: 202 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,65 +10,36 @@ class ImageUtils {
1010
* @param int $maxWidth - maximum new width
1111
* @param int $maxHeight - maximum new height
1212
* @param string $targetDir - target directory
13-
* @return path of the new image file or NULL if it could not be created.
13+
* @return string - the path of the new image file, e.g. /target/dir/basename.variation.png (or NULL in case of GD issues)
1414
*/
1515
public static function createThumbnail($imagePath, $maxWidth, $maxHeight, $targetDir = NULL) {
16-
$pathinfo = pathinfo($imagePath);
17-
$targetPath = '.';
18-
if ($targetDir == NULL) {
19-
$targetPath = $pathinfo['dirname'].'/'.$pathinfo['filename'].'.thumbnail.';
20-
} else {
21-
$targetPath = $targetDir.'/'.$pathinfo['filename'].'.thumbnail.';
22-
}
23-
if (class_exists('Imagick')) {
24-
$image = new \Imagick($imagePath);
25-
$image->thumbnailImage($maxWidth, $maxHeight, TRUE);
26-
$targetPath .= 'png';
27-
if (!$image->writeImage($targetPath)) {
28-
$targetPath = NULL;
29-
}
30-
} else {
31-
// We use GD
32-
$imageDetails = getimagesize($imagePath);
33-
$image = self::readImage($imagePath, $imageDetails);
34-
if ($image != NULL) {
35-
// Compute new dimensions
36-
$size = self::computeNewSize($imageDetails[0], $imageDetails[1], $maxWidth, $maxHeight);
16+
$targetPath = self::getNewPath($imagePath, 'thumbnail', $targetDir);
3717

38-
// Scale it
39-
$thumbnail = imagecreatetruecolor($size->width, $size-height);
40-
imagecopyresized($thumbnail, $image, 0, 0, 0, 0, $size->width, $size->height, $imageDetails[0], $imageDetails[1]);
41-
// Writing it
42-
$gdInfo = gd_info();
43-
// Preferential order PNG, JPEG, WEBP, XPM, WBMP, GIF, BMP
44-
if ($gdInfo['PNG Support']) {
45-
$targetPath .= 'png';
46-
if (!imagepng($thumbnail, $targetPath)) $targetPath = NULL;
47-
} else if ($gdInfo['JPEG Support']) {
48-
$targetPath .= 'jpg';
49-
if (!imagejpeg($thumbnail, $targetPath)) $targetPath = NULL;
50-
} else if ($gdInfo['WebP Support']) {
51-
$targetPath .= 'webp';
52-
if (!imagewebp($thumbnail, $targetPath)) $targetPath = NULL;
53-
} else if ($gdInfo['XPM Support']) {
54-
$targetPath .= 'xpm';
55-
if (!imagexbm($thumbnail, $targetPath)) $targetPath = NULL;
56-
} else if ($gdInfo['WBMP Support']) {
57-
$targetPath .= 'wbmp';
58-
if (!imagewbmp($thumbnail, $targetPath)) $targetPath = NULL;
59-
} else if ($gdInfo['GIF Create Support']) {
60-
$targetPath .= 'gif';
61-
if (!imagegif($thumbnail, $targetPath)) $targetPath = NULL;
62-
} else if ($gdInfo['BMP Support']) {
63-
$targetPath .= 'bmp';
64-
if (!imagebmp($thumbnail, $targetPath)) $targetPath = NULL;
65-
} else {
18+
if ($targetPath != NULL) {
19+
if (class_exists('Imagick')) {
20+
$image = new \Imagick($imagePath);
21+
$image->thumbnailImage($maxWidth, $maxHeight, TRUE);
22+
if (!$image->writeImage($targetPath)) {
6623
$targetPath = NULL;
6724
}
68-
imagedestroy($thumbnail);
69-
imagedestroy($image);
7025
} else {
71-
$targetPath = NULL;
26+
// We use GD
27+
$imageDetails = getimagesize($imagePath);
28+
$image = self::readImage($imagePath, $imageDetails);
29+
if ($image != NULL) {
30+
// Compute new dimensions
31+
$size = self::computeNewSize($imageDetails[0], $imageDetails[1], $maxWidth, $maxHeight);
32+
33+
// Scale it
34+
$thumbnail = imagecreatetruecolor($size->width, $size->height);
35+
imagecopyresized($thumbnail, $image, 0, 0, 0, 0, $size->width, $size->height, $imageDetails[0], $imageDetails[1]);
36+
// Writing it
37+
$targetPath = self::writeImage($thumbnail, $targetPath);
38+
imagedestroy($thumbnail);
39+
imagedestroy($image);
40+
} else {
41+
$targetPath = NULL;
42+
}
7243
}
7344
}
7445
return $targetPath;
@@ -130,6 +101,44 @@ public static function readImage($imagePath, $imageDetails = NULL) {
130101
return NULL;
131102
}
132103

104+
/**
105+
* Write an GD image to the specified path.
106+
* @param resource $image - the GD image resource
107+
* @param string $path - the path where to write to (must include the filetype extension)
108+
* @return string - the path when writing was successful, NULL otherwise
109+
*/
110+
public static function writeImage($image, $path) {
111+
$gdInfo = gd_info();
112+
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
113+
switch ($ext) {
114+
case 'png':
115+
if (!imagepng($thumbnail, $path)) $path = NULL;
116+
break;
117+
case 'jpg':
118+
case 'jpeg':
119+
if (!imagejpeg($thumbnail, $path)) $path = NULL;
120+
break;
121+
case 'webp':
122+
if (!imagewebp($thumbnail, $path)) $path = NULL;
123+
break;
124+
case 'xpm':
125+
if (!imagexbm($thumbnail, $path)) $path = NULL;
126+
break;
127+
case 'wbmp':
128+
if (!imagewbmp($thumbnail, $path)) $path = NULL;
129+
break;
130+
case 'gif':
131+
if (!imagegif($thumbnail, $path)) $path = NULL;
132+
break;
133+
case 'bmp':
134+
if (!imagebmp($thumbnail, $path)) $path = NULL;
135+
break;
136+
default:
137+
$path = NULL;
138+
}
139+
return $path;
140+
}
141+
133142
/**
134143
* Returns an object with width and height attributes to resize.
135144
* @param int $origWidth - original width
@@ -152,5 +161,145 @@ public static function computeNewSize($origWidth, $origHeight, $maxWidth, $maxHe
152161
}
153162
return $rc;
154163
}
164+
165+
/**
166+
* Cuts and scale the given image to new height and new width. The image will not be stretched or densed.
167+
* @param string $imagePath - path of image to read from
168+
* @param string $variation - The identifier to be included in the filename when writing the new image
169+
* @param int $newHeight - new height of image
170+
* @param int $newWidth - new width of image
171+
* @param string $targetDir - target directory
172+
* @return string the path to the new image file or NULL if action failed
173+
* @return string - the path of the new image file, e.g. /target/dir/basename.variation.png (or NULL in case of GD issues)
174+
*/
175+
public static function cropAndScale($imagePath, $variation, $newHeight, $newWidth, $options = NULL, $targetDir = NULL) {
176+
$targetPath = self::getNewPath($imagePath, $variation, $targetDir);
177+
if ($options == NULL) $options = self::cropAndScaleOptions();
178+
179+
if ($targetPath != NULL) {
180+
$actions = NULL;
181+
if (class_exists('Imagick')) {
182+
$image = new \Imagick($imagePath);
183+
$width = $image->getImageWidth();
184+
$height = $image->getImageHeight();
185+
$actions = self::computeCropAndScale($width, $height, $newWidth, $newHeight, $options);
186+
if ($actions->scale != 1) {
187+
$image->scaleImage($actions->factor * $width, 0);
188+
}
189+
if ($image->cropImage($actions->width, $actions->height, $actions->x, $actions->y)) {
190+
// Writing it
191+
if (!$image->writeImage($targetPath)) {
192+
$targetPath = NULL;
193+
}
194+
} else {
195+
$targetPath = NULL;
196+
}
197+
} else {
198+
// We use GD
199+
$imageDetails = getimagesize($imagePath);
200+
$actions = self::computeCropAndScale($imageDetails[0], $imageDetails[1], $newWidth, $newHeight, $options);
201+
202+
// Scale it
203+
$target = imagecreatetruecolor($actions->width, $actions->height);
204+
imagecopyresized($target, $image, 0, 0, $actions->x / $actions->factor, $actions->y / $actions->factor, $newWidth, $newHeight, $imageDetails[0] / $actions->factor, $imageDetails[1] / $actions->factor);
205+
$targetPath = self::writeImage($target, $targetPath);
206+
imagedestroy($target);
207+
imagedestroy($image);
208+
}
209+
}
210+
return $targetPath;
211+
}
212+
213+
/**
214+
* Creates options for the cropAndScale() function.
215+
* @param boolean $cropX - whether cropping width is permitted
216+
* @param boolean $cropY - whether cropping height is permitted
217+
* @param boolean $centerX - whether new image will be centered at X axis in case of cropping
218+
* @param boolean $centerY - whether new image will be centered at Y axis in case of cropping
219+
* @return object - the options for the cropAndScale() function
220+
*/
221+
public static function cropAndScaleOptions($centerX = TRUE, $centerY = FALSE) {
222+
$rc = new \stdClass;
223+
$rc->centerX = $centerX;
224+
$rc->centerY = $centerY;
225+
return $rc;
226+
}
227+
228+
public static function computeCropAndScale($origWidth, $origHeight, $maxWidth, $maxHeight, $options = NULL) {
229+
$rc = new \stdClass;
230+
if ($options == NULL) $options = self::cropAndScaleOptions();
231+
232+
233+
// Assume X scaling to maxWidth
234+
$rc->factor = $maxWidth / $origWidth;
235+
236+
// Positioning for cropping
237+
$rc->x = 0;
238+
$rc->y = 0;
239+
240+
// Compute potential target
241+
$rc->width = $maxWidth;
242+
$rc->height = $rc->factor * $origHeight;
243+
$rc->options = $options;
244+
245+
if ($rc->height < $maxHeight) {
246+
// scale up and crop along X axis
247+
$rc->factor = $maxHeight / $origHeight;
248+
$rc->width = $rc->factor * $origWidth;
249+
$rc->height = $maxHeight;
250+
if ($options->centerX) {
251+
$rc->x = ($rc->width - $maxWidth) / 2;
252+
}
253+
} else if ($rc->height > $maxHeight) {
254+
if ($options->centerY) {
255+
$rc->y = ($rc->height - $maxHeight) / 2;
256+
}
257+
}
258+
$rc->width = $maxWidth;
259+
$rc->height = $maxHeight;
260+
261+
return $rc;
262+
}
263+
264+
/**
265+
* Computes the variation path of an image file using a priority: PNG, JPEG, WEBP, XPM, WBMP, GIF, BMP
266+
* @param string $imagePath - the original image path
267+
* @param string $variation - the identifier to be included in new filename
268+
* @param string $targetDir - the target directory
269+
* @return string - the new path of the image file, e.g. /target/dir/basename.variation.png (or NULL in case of GD issues)
270+
*/
271+
public static function getNewPath($imagePath, $variation, $targetDir = NULL) {
272+
$pathinfo = pathinfo($imagePath);
273+
$targetPath = '.';
274+
if ($targetDir == NULL) {
275+
$targetPath = $pathinfo['dirname'].'/'.$pathinfo['filename'].'.'.$variation.'.';
276+
} else {
277+
$targetPath = $targetDir.'/'.$pathinfo['filename'].'.'.$variation.'.';
278+
}
279+
if (class_exists('Imagick')) {
280+
$targetPath .= 'png';
281+
} else {
282+
$gdInfo = gd_info();
283+
// Preferential order PNG, JPEG, WEBP, XPM, WBMP, GIF, BMP
284+
if ($gdInfo['PNG Support']) {
285+
$targetPath .= 'png';
286+
} else if ($gdInfo['JPEG Support']) {
287+
$targetPath .= 'jpg';
288+
} else if ($gdInfo['WebP Support']) {
289+
$targetPath .= 'webp';
290+
} else if ($gdInfo['XPM Support']) {
291+
$targetPath .= 'xpm';
292+
} else if ($gdInfo['WBMP Support']) {
293+
$targetPath .= 'wbmp';
294+
} else if ($gdInfo['GIF Create Support']) {
295+
$targetPath .= 'gif';
296+
} else if ($gdInfo['BMP Support']) {
297+
$targetPath .= 'bmp';
298+
} else {
299+
$targetPath = NULL;
300+
}
301+
}
302+
return $targetPath;
303+
}
155304
}
156305

0 commit comments

Comments
 (0)