Skip to content

Commit aedf71b

Browse files
committed
Image: added support for WEBP [Closes #73]
1 parent 71282e7 commit aedf71b

File tree

5 files changed

+55
-5
lines changed

5 files changed

+55
-5
lines changed

src/Utils/Image.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,15 @@ class Image
108108
const
109109
JPEG = IMAGETYPE_JPEG,
110110
PNG = IMAGETYPE_PNG,
111-
GIF = IMAGETYPE_GIF;
111+
GIF = IMAGETYPE_GIF,
112+
WEBP = 18; // IMAGETYPE_WEBP is available as of PHP 7.1
112113

113114
const EMPTY_GIF = "GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;";
114115

115116
/** @deprecated */
116117
const ENLARGE = 0;
117118

118-
static private $formats = [self::JPEG => 'jpeg', self::PNG => 'png', self::GIF => 'gif'];
119+
static private $formats = [self::JPEG => 'jpeg', self::PNG => 'png', self::GIF => 'gif', self::WEBP => 'webp'];
119120

120121
/** @var resource */
121122
private $image;
@@ -155,6 +156,9 @@ public static function fromFile($file, & $format = NULL)
155156
}
156157

157158
$format = @getimagesize($file)[2]; // @ - files smaller than 12 bytes causes read error
159+
if (!$format && PHP_VERSION_ID < 70100 && @file_get_contents($file, FALSE, NULL, 8, 4) === 'WEBP') { // @ - may not exists
160+
$format = self::WEBP;
161+
}
158162
if (!isset(self::$formats[$format])) {
159163
$format = NULL;
160164
throw new UnknownImageFileException(is_file($file) ? "Unknown type of file '$file'." : "File '$file' not found.");
@@ -510,7 +514,7 @@ public function place(Image $image, $left = 0, $top = 0, $opacity = 100)
510514
/**
511515
* Saves image to the file.
512516
* @param string filename
513-
* @param int quality 0..100 (for JPEG and PNG)
517+
* @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG)
514518
* @param int optional image type
515519
* @return bool TRUE on success or FALSE on failure.
516520
*/
@@ -537,6 +541,10 @@ public function save($file = NULL, $quality = NULL, $type = NULL)
537541
case self::GIF:
538542
return imagegif($this->image, $file);
539543

544+
case self::WEBP:
545+
$quality = $quality === NULL ? 80 : max(0, min(100, (int) $quality));
546+
return imagewebp($this->image, $file, $quality);
547+
540548
default:
541549
throw new Nette\InvalidArgumentException("Unsupported image type '$type'.");
542550
}
@@ -546,7 +554,7 @@ public function save($file = NULL, $quality = NULL, $type = NULL)
546554
/**
547555
* Outputs image to string.
548556
* @param int image type
549-
* @param int quality 0..100 (for JPEG and PNG)
557+
* @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG)
550558
* @return string
551559
*/
552560
public function toString($type = self::JPEG, $quality = NULL)
@@ -580,7 +588,7 @@ public function __toString()
580588
/**
581589
* Outputs image to browser.
582590
* @param int image type
583-
* @param int quality 0..100 (for JPEG and PNG)
591+
* @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG)
584592
* @return bool TRUE on success or FALSE on failure.
585593
*/
586594
public function send($type = self::JPEG, $quality = NULL)

tests/Utils/Image.factories.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ test(function () {
2424
});
2525

2626

27+
test(function () {
28+
if (!function_exists('imagecreatefromwebp')) {
29+
return;
30+
}
31+
$image = Image::fromFile(__DIR__ . '/images/logo.webp', $format);
32+
Assert::same(176, $image->getWidth());
33+
Assert::same(104, $image->getHeight());
34+
Assert::same(Image::WEBP, $format);
35+
});
36+
37+
2738
Assert::exception(function () {
2839
Image::fromFile('images/missing.png');
2940
}, Nette\Utils\UnknownImageFileException::class, "File 'images/missing.png' not found.");

tests/Utils/Image.save.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ test(function () use ($main) {
3333
});
3434

3535

36+
test(function () use ($main) {
37+
if (!function_exists('imagewebp')) {
38+
return;
39+
}
40+
41+
$main->save(TEMP_DIR . '/foo.webp');
42+
Assert::true(is_file(TEMP_DIR . '/foo.webp'));
43+
Assert::same('WEBP', file_get_contents(TEMP_DIR . '/foo.webp', FALSE, NULL, 8, 4));
44+
45+
$main->save(TEMP_DIR . '/foo.y', NULL, Image::WEBP);
46+
Assert::true(is_file(TEMP_DIR . '/foo.y'));
47+
Assert::same('WEBP', file_get_contents(TEMP_DIR . '/foo.y', FALSE, NULL, 8, 4));
48+
});
49+
50+
3651
Assert::exception(function () use ($main) { // invalid image type
3752
$main->save('foo', NULL, IMG_WBMP);
3853
}, Nette\InvalidArgumentException::class, sprintf('Unsupported image type \'%d\'.', IMG_WBMP));

tests/Utils/Image.send.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ test(function () use ($main) {
4343
});
4444

4545

46+
test(function () use ($main) {
47+
if (!function_exists('imagewebp')) {
48+
return;
49+
}
50+
51+
ob_start();
52+
$main->send(Image::WEBP);
53+
$data = ob_get_clean();
54+
55+
Assert::contains('WEBP', $data);
56+
if (PHP_SAPI !== 'cli') {
57+
Assert::contains('Content-Type: image/webp', headers_list());
58+
}
59+
});
60+
61+
4662
Assert::exception(function () use ($main) { // invalid image type
4763
$main->send(IMG_WBMP);
4864
}, Nette\InvalidArgumentException::class, sprintf('Unsupported image type \'%d\'.', IMG_WBMP));

tests/Utils/images/logo.webp

3.61 KB
Loading

0 commit comments

Comments
 (0)