Skip to content

Commit

Permalink
Merge pull request #36 from ArthurHoaro/feature/resampled
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthurHoaro authored Nov 24, 2022
2 parents 47675fc + 1a00a25 commit e2515d7
Show file tree
Hide file tree
Showing 19 changed files with 112 additions and 28 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,35 @@ Usage:
$wt = $wt->crop(true);
$conf = [WebThumbnailer::CROP => true];
```

### Resize Mode

This setting choose whether to use `imagecopyresized` (RESIZE mode) or `imagecopyresampled` (RESAMPLE mode):

* `RESAMPLE`: higher CPI usage, with better resized image rendering.
* `RESIZE`: faster and lower CPU usage, but the resized image might not look as good.

By default, this library uses `RESAMPLE` setting since the setting was introduced.

Example:

|---------------------RESIZE---------------------|---------------------RESAMPLE---------------------|

![](https://user-images.githubusercontent.com/28786873/195634626-ec80e2ac-43f1-4f00-a507-8ba30dc5dda7.jpg)
![](https://user-images.githubusercontent.com/28786873/195634635-87f84476-e923-461c-accf-d3e5988e33a5.jpg)

Usage:

```php
// Resize
$wt = $wt->resize();
$conf = [WebThumbnailer::RESIZE_MODE => WebThumbnailer::RESIZE];

// Resample
$wt = $wt->resample();
$conf = [WebThumbnailer::RESIZE_MODE => WebThumbnailer::RESAMPLE];
```

### Miscellaneous

* **NOCACHE**: Force the thumbnail to be resolved and downloaded instead of using cache files.
Expand Down
12 changes: 10 additions & 2 deletions src/Application/Thumbnailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Thumbnailer
public function __construct(string $url, array $options, ?array $server)
{
ApplicationUtils::checkExtensionRequirements(['gd']);
ApplicationUtils::checkPHPVersion('5.6', PHP_VERSION);
ApplicationUtils::checkPHPVersion('7.1', PHP_VERSION);

$this->url = $url;
$this->server = $server;
Expand Down Expand Up @@ -128,6 +128,13 @@ protected function setOptions(array $options): void
$this->options[WebThumbnailer::DEBUG] = false;
}

// Resize mode, defaults to resample
if (isset($options[WebThumbnailer::RESIZE_MODE])) {
$this->options[WebThumbnailer::RESIZE_MODE] = $options[WebThumbnailer::RESIZE_MODE];
} else {
$this->options[WebThumbnailer::RESIZE_MODE] = WebThumbnailer::RESAMPLE;
}

// Image size
$this->setSizeOptions($options);
}
Expand Down Expand Up @@ -354,7 +361,8 @@ protected function thumbnailDownload(string $thumbUrl)
$thumbPath,
$this->options[WebThumbnailer::MAX_WIDTH],
$this->options[WebThumbnailer::MAX_HEIGHT],
$this->options[WebThumbnailer::CROP]
$this->options[WebThumbnailer::CROP],
$this->options[WebThumbnailer::RESIZE_MODE]
);

if (!is_file($thumbPath)) {
Expand Down
1 change: 0 additions & 1 deletion src/Exception/BadRegexException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class BadRegexException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/BadRulesException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class BadRulesException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/CacheException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class CacheException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/DownloadException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class DownloadException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/IOException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class IOException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/ImageConvertException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class ImageConvertException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/MissingRequirementException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class MissingRequirementException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/NotAnImageException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class NotAnImageException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/NotImplementedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class NotImplementedException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/ThumbnailNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class ThumbnailNotFoundException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/UnsupportedDomainException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

class UnsupportedDomainException extends WebThumbnailerException
{

}
1 change: 0 additions & 1 deletion src/Exception/WebThumbnailerException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

abstract class WebThumbnailerException extends \Exception
{

}
7 changes: 5 additions & 2 deletions src/Utils/ImageUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use WebThumbnailer\Exception\ImageConvertException;
use WebThumbnailer\Exception\NotAnImageException;
use WebThumbnailer\WebThumbnailer;

/**
* Util class to manipulate GD images.
Expand Down Expand Up @@ -33,7 +34,8 @@ public static function generateThumbnail(
string $target,
int $maxWidth,
int $maxHeight,
bool $crop = false
bool $crop = false,
string $resizeMode = WebThumbnailer::RESAMPLE
): void {
if (!touch($target)) {
throw new ImageConvertException('Target file is not writable.');
Expand Down Expand Up @@ -74,8 +76,9 @@ public static function generateThumbnail(
throw new ImageConvertException('Could not generate the thumbnail from source image.');
}

$resizeFunction = $resizeMode === WebThumbnailer::RESIZE ? 'imagecopyresized' : 'imagecopyresampled';
if (
!imagecopyresized(
!$resizeFunction(
$targetImg,
$sourceImg,
0,
Expand Down
39 changes: 39 additions & 0 deletions src/WebThumbnailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ class WebThumbnailer
/** Debug mode. Throw exceptions. */
public const DEBUG = 'DEBUG';

/** Setting to define resize mode */
public const RESIZE_MODE = 'RESIZE_MODE';

/** Resize mode: less CPU usage but could end up pixellized */
public const RESIZE = 'RESIZE';

/** Resample mode: more CPU usage but smoother rendering */
public const RESAMPLE = 'RESAMPLE';

/** @var int|null */
protected $maxWidth = null;

Expand Down Expand Up @@ -79,6 +88,9 @@ class WebThumbnailer
/** @var string|null */
protected $downloadMode = null;

/** @var string|null */
protected $resizeMode = null;

/**
* Get the thumbnail for the given URL>
*
Expand Down Expand Up @@ -106,6 +118,7 @@ public function thumbnail(string $url, array $options = [])
static::DOWNLOAD_TIMEOUT => $this->downloadTimeout,
static::DOWNLOAD_MAX_SIZE => $this->downloadMaxSize,
static::CROP => $this->crop,
static::RESIZE_MODE => $this->resizeMode,
$this->downloadMode
],
$options
Expand Down Expand Up @@ -262,4 +275,30 @@ public function modeHotlinkStrict(): self

return $this;
}

/**
* Apply resize mode during resizing:
* lower CPU usage but sometimes rougher rendering.
*
* @return WebThumbnailer $this
*/
public function resize(): self
{
$this->resizeMode = static::RESIZE;

return $this;
}

/**
* Apply resample mode during resizing:
* slightly more CPU usage but smoother rendering.
*
* @return WebThumbnailer $this
*/
public function resample(): self
{
$this->resizeMode = static::RESAMPLE;

return $this;
}
}
42 changes: 30 additions & 12 deletions tests/WebThumbnailerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,28 @@ public function testDirectImageWithoutExtension(): void
/**
* URL which contains an opengraph image.
*/
public function testOpenGraphImage(): void
public function testOpenGraphImageResample(): void
{
$image = 'default/le-monde-full.jpg';
$this->regenerate($image, true, [0, 0, 160, 80]);
$expected = self::$regenerated . $image;
$url = self::LOCAL_SERVER . 'default/le-monde.html';
$wt = new WebThumbnailer();
$thumb = $wt->resample()->thumbnail($url);
$this->assertFileEquals($expected, $thumb);
}

/**
* URL which contains an opengraph image.
*/
public function testOpenGraphImageResize(): void
{
$image = 'default/le-monde.jpg';
$this->regenerate($image);
$this->regenerate($image, false, [], 'imagecopyresized');
$expected = self::$regenerated . $image;
$url = self::LOCAL_SERVER . 'default/le-monde.html';
$wt = new WebThumbnailer();
$thumb = $wt->thumbnail($url);
$thumb = $wt->resize()->thumbnail($url);
$this->assertFileEquals($expected, $thumb);
}

Expand Down Expand Up @@ -243,11 +257,11 @@ public function testDownloadDirectImageResizeHeightCrop(): void
public function testDownloadDirectImageResizeWidthHeightCrop(): void
{
$image = 'default/image-crop-341-341.png';
$this->regenerate($image, true);
$this->regenerate($image, true, [], 'imagecopyresized');
$expected = self::$regenerated . $image;
$url = self::LOCAL_SERVER . 'default/image-crop.png';
$wt = new WebThumbnailer();
$wt = $wt->maxHeight(341)->maxWidth(341)->crop(true);
$wt = $wt->maxHeight(341)->maxWidth(341)->resize()->crop(true);
$thumb = $wt->thumbnail($url);
$this->assertEquals(base64_encode(file_get_contents($expected)), base64_encode(file_get_contents($thumb)));
$this->assertFileEquals($expected, $thumb);
Expand All @@ -260,11 +274,11 @@ public function testDownloadDirectImageResizeWidthHeightCrop(): void
public function testDownloadDirectImageResizeWidthHeightCropOverride(): void
{
$image = 'default/image-crop-120-160.png';
$this->regenerate($image, true);
$this->regenerate($image, true, [], 'imagecopyresized');
$expected = self::$regenerated . $image;
$url = self::LOCAL_SERVER . 'default/image-crop.png';
$wt = new WebThumbnailer();
$wt = $wt->maxHeight(341)->maxWidth(341)->crop(true);
$wt = $wt->maxHeight(341)->maxWidth(341)->crop(true)->resize();
$thumb = $wt->thumbnail(
$url,
[
Expand Down Expand Up @@ -336,8 +350,12 @@ public function testHotlinkOpenGraphJsonConfig(): void
*
* @throws \Exception couldn't create the image.
*/
public function regenerate(string $image, bool $crop = false, array $cropParameters = []): void
{
public function regenerate(
string $image,
bool $crop = false,
array $cropParameters = [],
string $resizeFunc = 'imagecopyresampled'
): void {
$targetFolder = dirname(self::$regenerated . $image);
if (! is_dir($targetFolder)) {
mkdir($targetFolder, 0755, true);
Expand All @@ -350,15 +368,15 @@ public function regenerate(string $image, bool $crop = false, array $cropParamet

$targetImg = imagecreatetruecolor($width, $height);
if (
!imagecopyresized(
!$resizeFunc(
$targetImg,
$sourceImg,
0,
0,
0,
0,
$width,
$height,
$cropParameters[2] ?? $width,
$cropParameters[3] ?? $height,
$width,
$height
)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e2515d7

Please sign in to comment.