1
0
Fork 0
mirror of synced 2024-06-03 03:14:50 +12:00

Merge pull request #923 from lohanidamodar/feat-utopia-image-integration

feat-utopia-image-integration
This commit is contained in:
Eldad A. Fux 2021-02-24 10:07:00 +02:00 committed by GitHub
commit 2463e44124
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 121 additions and 471 deletions

View file

@ -133,8 +133,6 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
│ ├── Extend
│ ├── Network
│ ├── OpenSSL
│ ├── Resize
│ ├── Storage
│ ├── Task
│ ├── Template
│ ├── URL

View file

@ -1,28 +1,28 @@
<?php
use Utopia\App;
use Utopia\Exception;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Range;
use Utopia\Validator\URL;
use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Filesystem;
use Appwrite\Resize\Resize;
use Appwrite\URL\URL as URLParse;
use Appwrite\Utopia\Response;
use Utopia\Config\Config;
use Utopia\Validator\HexColor;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Utopia\App;
use Utopia\Cache\Adapter\Filesystem;
use Utopia\Cache\Cache;
use Utopia\Config\Config;
use Utopia\Exception;
use Utopia\Image\Image;
use Utopia\Validator\Boolean;
use Utopia\Validator\HexColor;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
$avatarCallback = function ($type, $code, $width, $height, $quality, $response) {
/** @var Appwrite\Utopia\Response $response */
$code = \strtolower($code);
$type = \strtolower($type);
$set = Config::getParam('avatar-'.$type, []);
$set = Config::getParam('avatar-' . $type, []);
if (empty($set)) {
throw new Exception('Avatar set not found', 404);
@ -37,17 +37,17 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
}
$output = 'png';
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = \md5('/v1/avatars/:type/:code-'.$code.$width.$height.$quality.$output);
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
$key = \md5('/v1/avatars/:type/:code-' . $code . $width . $height . $quality . $output);
$path = $set[$code];
$type = 'png';
if (!\is_readable($path)) {
throw new Exception('File not readable in '.$path, 500);
throw new Exception('File not readable in ' . $path, 500);
}
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
if ($data) {
//$output = (empty($output)) ? $type : $output;
@ -60,24 +60,23 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
;
}
$resize = new Resize(\file_get_contents($path));
$image = new Image(\file_get_contents($path));
$resize->crop((int) $width, (int) $height);
$image->crop((int) $width, (int) $height);
$output = (empty($output)) ? $type : $output;
$data = $resize->output($output, $quality);
$data = $image->output($output, $quality);
$cache->save($key, $data);
$response
->setContentType('image/png')
->addHeader('Expires', $date)
->addHeader('X-Appwrite-Cache', 'miss')
->send($data, null);
;
unset($resize);
unset($image);
};
App::get('/v1/avatars/credit-cards/:code')
@ -91,7 +90,7 @@ App::get('/v1/avatars/credit-cards/:code')
->label('sdk.description', '/docs/references/avatars/get-credit-card.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_IMAGE_PNG)
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: '.\implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))).'.')
->param('code', '', new WhiteList(\array_keys(Config::getParam('avatar-credit-cards'))), 'Credit Card Code. Possible values: ' . \implode(', ', \array_keys(Config::getParam('avatar-credit-cards'))) . '.')
->param('width', 100, new Range(0, 2000), 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
@ -160,11 +159,11 @@ App::get('/v1/avatars/image')
$quality = 80;
$output = 'png';
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = \md5('/v2/avatars/images-'.$url.'-'.$width.'/'.$height.'/'.$quality);
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
$key = \md5('/v2/avatars/images-' . $url . '-' . $width . '/' . $height . '/' . $quality);
$type = 'png';
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 7 /* 1 week */);
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 7/* 1 week */);
if ($data) {
return $response
@ -186,17 +185,17 @@ App::get('/v1/avatars/image')
}
try {
$resize = new Resize($fetch);
} catch (\Exception $exception) {
$image = new Image($fetch);
} catch (\Exception$exception) {
throw new Exception('Unable to parse image', 500);
}
$resize->crop((int) $width, (int) $height);
$image->crop((int) $width, (int) $height);
$output = (empty($output)) ? $type : $output;
$data = $resize->output($output, $quality);
$data = $image->output($output, $quality);
$cache->save($key, $data);
$response
@ -206,7 +205,7 @@ App::get('/v1/avatars/image')
->send($data);
;
unset($resize);
unset($image);
});
App::get('/v1/avatars/favicon')
@ -229,11 +228,11 @@ App::get('/v1/avatars/favicon')
$height = 56;
$quality = 80;
$output = 'png';
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
$key = \md5('/v2/avatars/favicon-'.$url);
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT'; // 45 days cache
$key = \md5('/v2/avatars/favicon-' . $url);
$type = 'png';
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE.'/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3 /* 3 months */);
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
$data = $cache->load($key, 60 * 60 * 24 * 30 * 3/* 3 months */);
if ($data) {
return $response
@ -316,7 +315,7 @@ App::get('/v1/avatars/favicon')
if (empty($outputHref) || empty($outputExt)) {
$default = \parse_url($url);
$outputHref = $default['scheme'].'://'.$default['host'].'/favicon.ico';
$outputHref = $default['scheme'] . '://' . $default['host'] . '/favicon.ico';
$outputExt = 'ico';
}
@ -343,13 +342,13 @@ App::get('/v1/avatars/favicon')
throw new Exception('Icon not found', 404);
}
$resize = new Resize($fetch);
$image = new Image($fetch);
$resize->crop((int) $width, (int) $height);
$image->crop((int) $width, (int) $height);
$output = (empty($output)) ? $type : $output;
$data = $resize->output($output, $quality);
$data = $image->output($output, $quality);
$cache->save($key, $data);
@ -359,7 +358,7 @@ App::get('/v1/avatars/favicon')
->addHeader('X-Appwrite-Cache', 'miss')
->send($data);
unset($resize);
unset($image);
});
App::get('/v1/avatars/qr')
@ -394,14 +393,14 @@ App::get('/v1/avatars/qr')
$response->addHeader('Content-Disposition', 'attachment; filename="qr.png"');
}
$resize = new Resize($qrcode->render($text));
$image = new Image($qrcode->render($text));
$resize->crop((int) $size, (int) $size);
$image->crop((int) $size, (int) $size);
$response
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
->setContentType('image/png')
->send($resize->output('png', 9))
->send($image->output('png', 9))
;
});
@ -437,10 +436,10 @@ App::get('/v1/avatars/initials')
['color' => '#610038', 'background' => '#f5d1e6'], // PINK
['color' => '#386100', 'background' => '#dcf1bd'], // LIME
['color' => '#615800', 'background' => '#f1ecba'], // YELLOW
['color' => '#610008', 'background' => '#f6d2d5'] // RED
['color' => '#610008', 'background' => '#f6d2d5'], // RED
];
$rand = \rand(0, \count($themes)-1);
$rand = \rand(0, \count($themes) - 1);
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
$words = \explode(' ', \strtoupper($name));
@ -457,23 +456,23 @@ App::get('/v1/avatars/initials')
}
$length = \count($words);
$rand = \substr($code,-1);
$background = (!empty($background)) ? '#'.$background : $themes[$rand]['background'];
$color = (!empty($color)) ? '#'.$color : $themes[$rand]['color'];
$rand = \substr($code, -1);
$background = (!empty($background)) ? '#' . $background : $themes[$rand]['background'];
$color = (!empty($color)) ? '#' . $color : $themes[$rand]['color'];
$image = new \Imagick();
$draw = new \ImagickDraw();
$fontSize = \min($width, $height) / 2;
$draw->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
$image->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-500.ttf");
$draw->setFont(__DIR__ . "/../../../public/fonts/poppins-v9-latin-500.ttf");
$image->setFont(__DIR__ . "/../../../public/fonts/poppins-v9-latin-500.ttf");
$draw->setFillColor(new \ImagickPixel($color));
$draw->setFontSize($fontSize);
$draw->setTextAlignment(\Imagick::ALIGN_CENTER);
$draw->annotation($width / 1.97, ($height / 2) + ($fontSize / 3), $initials);
$image->newImage($width, $height, $background);
$image->setImageFormat("png");
$image->drawImage($draw);
@ -481,7 +480,7 @@ App::get('/v1/avatars/initials')
//$image->setImageCompressionQuality(9 - round(($quality / 100) * 9));
$response
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
->setContentType('image/png')
->send($image->getImageBlob())
;

View file

@ -18,7 +18,7 @@ use Utopia\Storage\Validator\File;
use Utopia\Storage\Validator\FileSize;
use Utopia\Storage\Validator\Upload;
use Utopia\Storage\Compression\Algorithms\GZIP;
use Appwrite\Resize\Resize;
use Utopia\Image\Image;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\Utopia\Response;
use Utopia\Config\Config;
@ -332,17 +332,17 @@ App::get('/v1/storage/files/:fileId/preview')
$source = $compressor->decompress($source);
}
$resize = new Resize($source);
$image = new Image($source);
$resize->crop((int) $width, (int) $height);
$image->crop((int) $width, (int) $height);
if (!empty($background)) {
$resize->setBackground('#'.$background);
$image->setBackground('#'.$background);
}
$output = (empty($output)) ? $type : $output;
$data = $resize->output($output, $quality);
$data = $image->output($output, $quality);
$cache->save($key, $data);
@ -353,7 +353,7 @@ App::get('/v1/storage/files/:fileId/preview')
->send($data)
;
unset($resize);
unset($image);
});
App::get('/v1/storage/files/:fileId/download')

View file

@ -47,7 +47,8 @@
"utopia-php/domains": "0.2.*",
"utopia-php/swoole": "0.2.*",
"utopia-php/system": "0.4.*",
"utopia-php/storage": "0.2.*",
"utopia-php/storage": "0.4.*",
"utopia-php/image": "0.1.*",
"resque/php-resque": "1.3.6",
"matomo/device-detector": "3.13.0",

64
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5893b378d1dcda91aedf77059f4b0efb",
"content-hash": "90ff57f6e7de570c7bdffad74829f187",
"packages": [
{
"name": "adhocore/jwt",
@ -1595,6 +1595,48 @@
},
"time": "2020-12-26T12:02:39+00:00"
},
{
"name": "utopia-php/image",
"version": "0.1.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/image",
"reference": "66e38db211b1d6fe93de09d82606641e0f996e42"
},
"require": {
"chillerlan/php-qrcode": "4.3.0",
"ext-imagick": "*",
"php": ">=7.4"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
"vimeo/psalm": "4.0.1"
},
"type": "library",
"autoload": {
"psr-4": {
"Utopia\\Image\\": "src/Image"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Eldad Fux",
"email": "eldad@appwrite.io"
}
],
"description": "A simple Image manipulation library",
"keywords": [
"framework",
"image",
"php",
"upf",
"utopia"
],
"time": "2021-02-19T05:09:46+00:00"
},
{
"name": "utopia-php/locale",
"version": "0.3.3",
@ -1753,16 +1795,16 @@
},
{
"name": "utopia-php/storage",
"version": "0.2.0",
"version": "0.4.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/storage.git",
"reference": "27bfd663c9b2a17ac0911522a87f42bee834df95"
"reference": "86f749f2d79268528732e560f77dde0155e162ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/storage/zipball/27bfd663c9b2a17ac0911522a87f42bee834df95",
"reference": "27bfd663c9b2a17ac0911522a87f42bee834df95",
"url": "https://api.github.com/repos/utopia-php/storage/zipball/86f749f2d79268528732e560f77dde0155e162ca",
"reference": "86f749f2d79268528732e560f77dde0155e162ca",
"shasum": ""
},
"require": {
@ -1799,9 +1841,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/storage/issues",
"source": "https://github.com/utopia-php/storage/tree/0.2.0"
"source": "https://github.com/utopia-php/storage/tree/0.4.1"
},
"time": "2021-01-27T12:21:27+00:00"
"time": "2021-02-19T05:04:44+00:00"
},
{
"name": "utopia-php/swoole",
@ -4738,12 +4780,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "2a6f75224a537ee506e9fa1e6fc4200ad411ffd9"
"reference": "539148499aaafa5058d534582f61ce2a66480987"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/2a6f75224a537ee506e9fa1e6fc4200ad411ffd9",
"reference": "2a6f75224a537ee506e9fa1e6fc4200ad411ffd9",
"url": "https://api.github.com/repos/symfony/console/zipball/539148499aaafa5058d534582f61ce2a66480987",
"reference": "539148499aaafa5058d534582f61ce2a66480987",
"shasum": ""
},
"require": {
@ -4828,7 +4870,7 @@
"type": "tidelift"
}
],
"time": "2021-02-17T15:27:35+00:00"
"time": "2021-02-18T11:02:40+00:00"
},
{
"name": "symfony/polyfill-ctype",

View file

@ -1,220 +0,0 @@
<?php
namespace Appwrite\Resize;
use Exception;
use Imagick;
class Resize
{
private $image;
private $width;
private $height;
/**
* @param string $data
*
* @throws Exception
*/
public function __construct($data)
{
$this->image = new Imagick();
$this->image->readImageBlob($data);
$this->width = $this->image->getImageWidth();
$this->height = $this->image->getImageHeight();
}
/**
* @param int $width
* @param int $height
*
* @return Resize
*
* @throws \Throwable
*/
public function crop(int $width, int $height)
{
$originalAspect = $this->width / $this->height;
if (empty($width)) {
$width = $height * $originalAspect;
}
if (empty($height)) {
$height = $width / $originalAspect;
}
if (empty($height) && empty($width)) {
$height = $this->height;
$width = $this->width;
}
if ($this->image->getImageFormat() == 'GIF') {
$this->image = $this->image->coalesceImages();
foreach ($this->image as $frame) {
$frame->cropThumbnailImage($width, $height);
}
$this->image->deconstructImages();
} else {
$this->image->cropThumbnailImage($width, $height);
}
return $this;
}
/**
* @param $color
*
* @return Resize
*
* @throws \Throwable
*/
public function setBackground($color)
{
$this->image->setImageBackgroundColor($color);
$this->image = $this->image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
return $this;
}
/**
* Output.
*
* Prints manipulated image.
*
* @param string $type
* @param int $quality
*
* @return string
*
* @throws Exception
*/
public function output(string $type, int $quality = 75)
{
return $this->save(null, $type, $quality);
}
/**
* @param string $path
* @param $type
* @param int $quality
*
* @return string
*
* @throws Exception
*/
public function save(string $path = null, string $type = '', int $quality = 75)
{
// Create directory with write permissions
if (null !== $path && !\file_exists(\dirname($path))) {
if (!@\mkdir(\dirname($path), 0755, true)) {
throw new Exception('Can\'t create directory '.\dirname($path));
}
}
switch ($type) {
case 'jpg':
case 'jpeg':
$this->image->setImageCompressionQuality($quality);
$this->image->setImageFormat('jpg');
break;
case 'gif':
$this->image->setImageFormat('gif');
break;
case 'webp':
try {
$this->image->setImageFormat('webp');
} catch (\Throwable $th) {
$signature = $this->image->getImageSignature();
$temp = '/tmp/temp-'.$signature.'.'.\strtolower($this->image->getImageFormat());
$output = '/tmp/output-'.$signature.'.webp';
// save temp
$this->image->writeImages($temp, true);
// convert temp
\exec("cwebp -quiet -metadata none -q $quality $temp -o $output");
$data = \file_get_contents($output);
//load webp
if (empty($path)) {
return $data;
} else {
\file_put_contents($path, $data, LOCK_EX);
}
$this->image->clear();
$this->image->destroy();
//delete webp
\unlink($output);
\unlink($temp);
return;
}
break;
case 'png':
/* Scale quality from 0-100 to 0-9 */
$scaleQuality = \round(($quality / 100) * 9);
/* Invert quality setting as 0 is best, not 9 */
$invertScaleQuality = 9 - $scaleQuality;
$this->image->setImageCompressionQuality($invertScaleQuality);
$this->image->setImageFormat('png');
break;
default:
throw new Exception('Invalid output type given');
break;
}
if (empty($path)) {
return $this->image->getImagesBlob();
} else {
$this->image->writeImages($path, true);
}
$this->image->clear();
$this->image->destroy();
}
/**
* @param int $newHeight
*
* @return int
*/
protected function getSizeByFixedHeight(int $newHeight):int
{
$ratio = $this->width / $this->height;
$newWidth = $newHeight * $ratio;
return $newWidth;
}
/**
* @param int $newWidth
*
* @return int
*/
protected function getSizeByFixedWidth(int $newWidth):int
{
$ratio = $this->height / $this->width;
$newHeight = $newWidth * $ratio;
return $newHeight;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View file

@ -1,170 +0,0 @@
<?php
namespace Appwrite\Tests;
use Appwrite\Resize\Resize;
use PHPUnit\Framework\TestCase;
class ResizeTest extends TestCase
{
public function setUp(): void
{
}
public function tearDown(): void
{
}
public function testCrop100x100()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/100x100.jpg';
$resize->crop(100, 100);
$resize->save($target, 'jpg', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertEquals('JPEG', $image->getImageFormat());
\unlink($target);
}
public function testCrop100x400()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/100x400.jpg';
$resize->crop(100, 400);
$resize->save($target, 'jpg', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(400, $image->getImageHeight());
$this->assertEquals('JPEG', $image->getImageFormat());
\unlink($target);
}
public function testCrop400x100()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/400x100.jpg';
$resize->crop(400, 100);
$resize->save($target, 'jpg', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(400, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertEquals('JPEG', $image->getImageFormat());
\unlink($target);
}
public function testCrop100x100WEBP()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/100x100.webp';
$original = __DIR__.'/../../resources/resize/100x100.webp';
$resize->crop(100, 100);
$resize->save($target, 'webp', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertTrue(in_array($image->getImageFormat(), ['PAM', 'WEBP']));
\unlink($target);
}
public function testCrop100x100PNG()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/100x100.png';
$original = __DIR__.'/../../resources/resize/100x100.png';
$resize->crop(100, 100);
$resize->save($target, 'png', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertGreaterThan(15000, \filesize($target));
$this->assertLessThan(30000, \filesize($target));
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertEquals('PNG', $image->getImageFormat());
\unlink($target);
}
public function testCrop100x100PNGQuality30()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-1.jpg'));
$target = __DIR__.'/100x100-q30.jpg';
$original = __DIR__.'/../../resources/resize/100x100-q30.jpg';
$resize->crop(100, 100);
$resize->save($target, 'jpg', 10);
$this->assertEquals(\is_readable($target), true);
$this->assertGreaterThan(500, \filesize($target));
$this->assertLessThan(2000, \filesize($target));
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertEquals('JPEG', $image->getImageFormat());
\unlink($target);
}
public function testCrop100x100GIF()
{
$resize = new Resize(\file_get_contents(__DIR__ . '/../../resources/disk-a/kitten-3.gif'));
$target = __DIR__.'/100x100.gif';
$original = __DIR__.'/../../resources/resize/100x100.gif';
$resize->crop(100, 100);
$resize->save($target, 'gif', 100);
$this->assertEquals(\is_readable($target), true);
$this->assertGreaterThan(400000, \filesize($target));
$this->assertLessThan(800000, \filesize($target));
$this->assertEquals(\mime_content_type($target), \mime_content_type($original));
$this->assertNotEmpty(\md5(\file_get_contents($target)));
$image = new \Imagick($target);
$this->assertEquals(100, $image->getImageWidth());
$this->assertEquals(100, $image->getImageHeight());
$this->assertEquals('GIF', $image->getImageFormat());
\unlink($target);
}
}