started working on 0.2 overhaul

This commit is contained in:
Joby 2023-09-11 03:28:59 +00:00
parent a92ab71dfd
commit 37ab60d81b
23 changed files with 169 additions and 495 deletions

View file

@ -1,30 +0,0 @@
<?php
use mageekguy\atoum\reports;
$runner
->addTestsFromDirectory(__DIR__ . '/tests/units');
$runner->getScore()->getCoverage()->excludeDirectory(__DIR__ . '/tests/units/mock');
$travis = getenv('TRAVIS');
if ($travis) {
$script->addDefaultReport();
$coverallsToken = getenv('COVERALLS_REPO_TOKEN');
if ($coverallsToken) {
$coverallsReport = new reports\asynchronous\coveralls('classes', $coverallsToken);
$defaultFinder = $coverallsReport->getBranchFinder();
$coverallsReport
->setBranchFinder(function () use ($defaultFinder) {
if (($branch = getenv('TRAVIS_BRANCH')) === false) {
$branch = $defaultFinder();
}
return $branch;
}
)
->setServiceName('travis-ci')
->setServiceJobId(getenv('TRAVIS_JOB_ID'))
->addDefaultWriter()
;
$runner->addReport($coverallsReport);
}
}

19
.devcontainer/Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM ubuntu:22.04
# prepare to install php 8.2
RUN apt update && apt install -y software-properties-common
RUN add-apt-repository ppa:ondrej/php
RUN apt update
# install php 8.2 and other fundamental packages
RUN export DEBIAN_FRONTEND=noninteractive; apt install -y --no-install-recommends php8.2 php-curl git openssl unzip
# install composer and its CA certificates
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
COPY --from=composer:latest /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# install the PHP extensions that basically all PHP projects should need
RUN export DEBIAN_FRONTEND=noninteractive; apt install -y php8.2-opcache php-xdebug php-mbstring php-zip php-gd php-xml
# install extensions that are more project-specific
RUN export DEBIAN_FRONTEND=noninteractive; apt install -y php-gmagick

View file

@ -0,0 +1,37 @@
{
// build from dockerfile
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
// specify run arguments
"runArgs": [
"--dns=8.8.8.8" // for some reason DNS doesn't work right unless we explicitly name a DNS server
],
// mount entire sites_v2 directory, so we can access global config and shared DB
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace/${localWorkspaceFolderBasename},type=bind,consistency=cached",
"workspaceFolder": "/workspace/${localWorkspaceFolderBasename}",
// specify extensions that we want
"customizations": {
"vscode": {
"extensions": [
"DEVSENSE.intelli-php-vscode",
"DEVSENSE.phptools-vscode",
"DEVSENSE.profiler-php-vscode",
"DEVSENSE.composer-php-vscode",
"SanderRonde.phpstan-vscode",
"sibiraj-s.vscode-scss-formatter",
"mrmlnc.vscode-scss",
"Gruntfuggly.todo-tree",
"redhat.vscode-yaml",
"oliversturm.fix-json",
"ecmel.vscode-html-css",
"yzhang.markdown-all-in-one",
"DavidAnson.vscode-markdownlint",
"helixquar.randomeverything",
"neilbrayfield.php-docblocker",
"ms-vscode.test-adapter-converter"
]
}
}
}

View file

@ -1,9 +0,0 @@
language: php
php:
- 7.1
- 7.2
- 7.3
- 7.4
install:
- composer install
script: composer test

View file

@ -1,9 +1,6 @@
# image-transform
[![Build Status](https://travis-ci.org/jobyone/image-transform.svg?branch=main)](https://travis-ci.org/jobyone/image-transform)
[![Coverage Status](https://coveralls.io/repos/github/jobyone/image-transform/badge.svg?branch=main)](https://coveralls.io/github/jobyone/image-transform?branch=main)
A tightly-focused library for performing a very limited set of simple image transformations. This library's purpose is to eschew the standard kitchen sink approach to PHP image libraries in favor of high performance, wide driver support, and a dead simple API.
A tightly-focused library for performing a very limited set of simple image transformations. This library's purpose is to eschew the standard kitchen sink approach to PHP image libraries in favor of high performance, wider driver support, and a dead simple API.
## Current state
@ -11,12 +8,12 @@ This library is under active development, and until a 1.0 release is made you sh
### Current progress
| Driver | Rotate | Mirror | Resize | Crop | Overlay | Grayscale | Colorize |
| :--------- | :----: | :----: | :----: | :--: | :-----: | :-------: | :------: |
| GD | X | X | X | X | | | |
| Imagick | | | | | | | |
| Gmagick | | | | | | | |
| ImagickCLI | X | X | X | X | | | |
| Driver | Rotate | Mirror | Resize | Crop |
| :--------- | :----: | :----: | :----: | :--: |
| GD | X | X | X | X |
| Imagick | | | | |
| Gmagick | | | | |
| ImagickCLI | X | X | X | X |
## Roadmap
@ -57,7 +54,7 @@ More complex, and also lesser used effects/stages that may or may not make it in
#### Order of operations
In the name of simplicity and ease of use, the effective order of operations will always be as reflected above:
In the name of simplicity, ease of use, and performance, the effective order of operations will always and only be:
1. Orientation
2. Resizing and cropping

View file

@ -15,16 +15,16 @@
}
},
"suggest": {
"ext-imagick": "to use the Imagick implementation",
"ext-imagick": "to use the ImageMagick implementation",
"ext-gmagick": "to use the Gmagick implementation"
},
"require": {
"php": ">=7.1",
"php": ">=8.1",
"ext-gd": "*"
},
"require-dev": {
"atoum/atoum": "^3.4",
"atoum/stubs": "^2.6"
"ext-gmagick": "*",
"ext-gd": "*"
},
"autoload-dev": {
"psr-4": {

View file

@ -1,12 +1,12 @@
<?php
use ByJoby\ImageTransform\Drivers\ImagickCLIDriver;
use ByJoby\ImageTransform\Drivers\MagickCliDriver;
use ByJoby\ImageTransform\Sizers\Cover;
include __DIR__ . '/../vendor/autoload.php';
// first step is instantiate a Driver, in this case ImagickCLI
$driver = new ImagickCLIDriver();
$driver = new MagickCliDriver();
// instantiate an Image object using a source file and Sizer
// in this example we're covering a 200x500 box

25
src/DefaultDriver.php Normal file
View file

@ -0,0 +1,25 @@
<?php
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform;
use ByJoby\ImageTransform\Drivers\GDDriver;
/**
* Stores a default driver to be used when a driver is not set for an Image.
* Defaults to a GD driver.
*/
class DefaultDriver
{
protected $driver;
public static function get(): DriverInterface
{
return static::$driver
?? static::$driver = new GDDriver();
}
public static function set(DriverInterface $driver): void
{
static::$driver = $driver;
}
}

View file

@ -6,6 +6,24 @@ use ByJoby\ImageTransform\Sizers\AbstractSizer;
interface DriverInterface
{
public function image(string $src, AbstractSizer $sizer): Image;
/**
* Save an image with its current settings. If a filename is specified the
* image will be saved to it and null returned, otherwise the image will be
* returned as a string.
*
* @param Image $image
* @param string|null $filename
* @return string|null
*/
public function save(Image $image, ?string $filename = null): ?string;
}
/**
* Set the temp directory in which files should be created if necessary for
* processing images. A directory in the system temp folder will be used by
* default.
*
* @param string $dir
* @return static
*/
public function setTempDir(string $dir): static;
}

View file

@ -2,7 +2,7 @@
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\Drivers;
abstract class AbstractCLIDriver extends AbstractDriver
abstract class AbstractCliDriver extends AbstractDriver
{
public function __construct()
{

View file

@ -9,20 +9,11 @@ use ByJoby\ImageTransform\Sizers\AbstractSizer;
abstract class AbstractDriver implements DriverInterface
{
protected $tempDir = null;
protected $chmod = 0775;
protected $chmod_dir = 0775;
protected $chmod_file = 0665;
abstract protected function doSave(Image $image, string $filename);
public function __clone()
{
$this->tempDir = null;
}
public function image(string $src, AbstractSizer $sizer): Image
{
return new Image($src, $this, $sizer);
}
public function tempDir(): string
{
if (!$this->tempDir) {
@ -31,12 +22,13 @@ abstract class AbstractDriver implements DriverInterface
return $this->tempDir;
}
protected function setTempDir(string $dir)
public function setTempDir(string $dir): static
{
if (!$this->mkdir($dir)) {
throw new \Exception("Temp directory " . htmlentities($dir) . " doesn't exist or isn't writeable, and couldn't be created.");
}
$this->tempDir = $dir;
return $this;
}
protected function mkdir(string $dir)
@ -52,7 +44,7 @@ abstract class AbstractDriver implements DriverInterface
if (is_dir($parent)) {
// check parent permissions
if (!is_writeable($parent)) {
chmod($parent, $this->chmod);
chmod($parent, $this->chmod_dir);
}
if (!is_writeable($parent)) {
return false;
@ -61,7 +53,7 @@ abstract class AbstractDriver implements DriverInterface
if (!mkdir($dir)) {
return false;
}
chmod($dir, $this->chmod);
chmod($dir, $this->chmod_dir);
return is_writeable($dir);
} else {
// parent doesn't exist, so recursive call failed
@ -83,11 +75,14 @@ abstract class AbstractDriver implements DriverInterface
touch($filename);
}
$this->doSave($image, realpath($filename));
chmod($filename, $this->chmod_file);
return null;
} else {
$filename = $this->tempDir() . '/save.jpg';
$filename = $this->tempDir() . '/' . uniqid() . '.jpg';
$this->doSave($image, $filename);
return file_get_contents($filename);
$output = file_get_contents($filename);
unlink($filename);
return $output;
}
}
}
}

View file

@ -5,8 +5,9 @@ namespace ByJoby\ImageTransform\Drivers;
use ByJoby\ImageTransform\Image;
/**
* This driver uses PHP's built-in GD libary. This is by far the slowest
* driver, but support is basically universal.
* This driver uses PHP's built-in GD libary. This is by far the slowest driver,
* and its memory use is absolutely atrocious for large images, but support is
* basically universal.
*/
class GDDriver extends AbstractExtensionDriver
{

View file

@ -5,13 +5,13 @@ namespace ByJoby\ImageTransform\Drivers;
use ByJoby\ImageTransform\Image;
/**
* This driver uses exec() and command-line ImageMagick utilities to
* transform images. It is likely approaching the limits of how fast this
* library can possibly be. The downside is that it will only run if
* you have exec() enabled, and your server allows it to execute the
* ImageMagick binaries.
* This driver uses exec() and command-line ImageMagick (or Gmagick) utilities
* to transform images. It is likely approaching the limits of how fast this
* library can possibly be. The downside is that it will only run if you have
* exec() enabled, and your server allows it to execute the ImageMagick/Gmagick
* binaries and use them to read and write image files.
*/
class ImagickCLIDriver extends AbstractCLIDriver
class MagickCliDriver extends AbstractCliDriver
{
protected $mogrify_executable;

View file

@ -3,21 +3,23 @@
namespace ByJoby\ImageTransform;
use ByJoby\ImageTransform\Sizers\AbstractSizer;
use ByJoby\ImageTransform\Sizers\Original;
class Image
{
protected $source, $driver;
protected $originalWidth, $originalHeight;
protected $source;
protected $driver;
protected $originalWidth;
protected $originalHeight;
protected $rotation = 0;
protected $flipH = false;
protected $flipV = false;
protected $sizer = null;
public function __construct(string $source, DriverInterface $driver, AbstractSizer $sizer)
public function __construct(string $source, AbstractSizer|null $sizer = null)
{
$this->setSource($source);
$this->setSizer($sizer);
$this->driver = clone $driver;
$this->setSizer($sizer ?? new Original());
}
public function source(): string
@ -25,7 +27,7 @@ class Image
return $this->source;
}
public function setSource(string $source)
public function setSource(string $source): static
{
// set source
$this->source = realpath($source);
@ -41,6 +43,8 @@ class Image
}
// get height/width
list($this->originalWidth, $this->originalHeight) = getimagesize($this->source);
// return self
return $this;
}
public function sizer(): AbstractSizer
@ -48,15 +52,17 @@ class Image
return $this->sizer;
}
public function setSizer(AbstractSizer $sizer)
public function setSizer(AbstractSizer $sizer): static
{
$this->sizer = clone $sizer;
$this->sizer->image($this);
return $this;
}
public function rotate(int $steps = 1)
public function rotate(int $steps = 1): static
{
$this->rotation = ($this->rotation + $steps) % 4;
return $this;
}
public function rotation(): int
@ -64,22 +70,24 @@ class Image
return $this->rotation;
}
public function flipH()
public function flipH(): static
{
$this->flipH = !$this->flipH;
return $this;
}
public function flipV()
public function flipV(): static
{
$this->flipV = !$this->flipV;
return $this;
}
public function getFlipH()
public function getFlipH(): bool
{
return $this->flipH;
}
public function getFlipV()
public function getFlipV(): bool
{
return $this->flipV;
}
@ -114,8 +122,14 @@ class Image
return $this->originalHeight;
}
public function save(string $file)
public function driver(): DriverInterface
{
$this->driver->save($this, $file);
return $this->driver ?? DefaultDriver::get();
}
}
public function save(string $file): static
{
$this->driver()->save($this, $file);
return $this;
}
}

View file

@ -2,6 +2,9 @@
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\Sizers;
/**
* This sizer does no manipulations and keeps the image the size it originally was.
*/
class Original extends AbstractSizer
{
public function resizeToWidth(): ?int

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

View file

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -1,173 +0,0 @@
<?php
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\tests\units\Sizers;
use atoum;
use ByJoby\ImageTransform\Sizers\Cover as SizerUnderTest;
use ByJoby\ImageTransform\tests\units\mock\MockDriver;
class Cover extends atoum
{
public function testPortraitWhenImageIsTaller()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',100,150))
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(150)
->variable($image->sizer()->resizeToWidth())->isEqualTo(100)
->variable($image->sizer()->resizeToHeight())->isEqualTo(200)
->variable($image->sizer()->cropToWidth())->isEqualTo(100)
->variable($image->sizer()->cropToHeight())->isEqualTo(150)
->given($image->rotate())
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(150)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(150)
->variable($image->sizer()->cropToWidth())->isEqualTo(100)
->variable($image->sizer()->cropToHeight())->isEqualTo(150)
;
}
public function testPortraitWhenImageIsShorter()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',50,300))
->integer($image->width())->isEqualTo(50)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(150)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(50)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
->given($image->rotate())
->integer($image->width())->isEqualTo(50)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(600)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(50)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
;
}
public function testPortraitWithSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',75,300))
->integer($image->width())->isEqualTo(75)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(75)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
;
}
public function testPortraitWithLandscapeImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',100,200))
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(200)
->variable($image->sizer()->resizeToWidth())->isEqualTo(400)
->variable($image->sizer()->resizeToHeight())->isEqualTo(200)
->variable($image->sizer()->cropToWidth())->isEqualTo(100)
->variable($image->sizer()->cropToHeight())->isEqualTo(200)
;
}
public function testLandscapeWhenImageIsTaller()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',150,100))
->integer($image->width())->isEqualTo(150)
->integer($image->height())->isEqualTo(100)
->variable($image->sizer()->resizeToWidth())->isEqualTo(200)
->variable($image->sizer()->resizeToHeight())->isEqualTo(100)
->variable($image->sizer()->cropToWidth())->isEqualTo(150)
->variable($image->sizer()->cropToHeight())->isEqualTo(100)
;
}
public function testLandscapeWhenImageIsShorter()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',300,75))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(150)
->variable($image->sizer()->cropToWidth())->isEqualTo(300)
->variable($image->sizer()->cropToHeight())->isEqualTo(75)
;
}
public function testLandscapeWithSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',300,75))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(300)
->variable($image->sizer()->cropToHeight())->isEqualTo(75)
;
}
public function testLandscapeWithPortraitImage()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',200,100))
->integer($image->width())->isEqualTo(200)
->integer($image->height())->isEqualTo(100)
->variable($image->sizer()->resizeToWidth())->isEqualTo(200)
->variable($image->sizer()->resizeToHeight())->isEqualTo(400)
->variable($image->sizer()->cropToWidth())->isEqualTo(200)
->variable($image->sizer()->cropToHeight())->isEqualTo(100)
;
}
public function testWithSmallSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',300,300))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(300)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
;
}
public function testWithSmallLandscapeImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',300,300))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(600)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isEqualTo(300)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
;
}
public function testWithSmallPortraitImage()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',300,300))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(600)
->variable($image->sizer()->cropToWidth())->isEqualTo(300)
->variable($image->sizer()->cropToHeight())->isEqualTo(300)
;
}
protected function image(string $path, int $width, int $height)
{
$driver = new MockDriver();
return $driver->image($path, new SizerUnderTest($width, $height));
}
}

View file

@ -1,173 +0,0 @@
<?php
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\tests\units\Sizers;
use atoum;
use ByJoby\ImageTransform\Sizers\Fit as SizerUnderTest;
use ByJoby\ImageTransform\tests\units\mock\MockDriver;
class Fit extends atoum
{
public function testPortraitWhenImageIsTaller()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',100,150))
->integer($image->width())->isEqualTo(75)
->integer($image->height())->isEqualTo(150)
->variable($image->sizer()->resizeToWidth())->isEqualTo(75)
->variable($image->sizer()->resizeToHeight())->isEqualTo(150)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
->given($image->rotate())
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(50)
->variable($image->sizer()->resizeToWidth())->isEqualTo(100)
->variable($image->sizer()->resizeToHeight())->isEqualTo(50)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testPortraitWhenImageIsShorter()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',50,300))
->integer($image->width())->isEqualTo(50)
->integer($image->height())->isEqualTo(100)
->variable($image->sizer()->resizeToWidth())->isEqualTo(50)
->variable($image->sizer()->resizeToHeight())->isEqualTo(100)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
->given($image->rotate())
->integer($image->width())->isEqualTo(50)
->integer($image->height())->isEqualTo(25)
->variable($image->sizer()->resizeToWidth())->isEqualTo(50)
->variable($image->sizer()->resizeToHeight())->isEqualTo(25)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testPortraitWithSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',75,300))
->integer($image->width())->isEqualTo(75)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(75)
->variable($image->sizer()->resizeToHeight())->isEqualTo(75)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testPortraitWithLandscapeImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',100,200))
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(50)
->variable($image->sizer()->resizeToWidth())->isEqualTo(100)
->variable($image->sizer()->resizeToHeight())->isEqualTo(50)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testLandscapeWhenImageIsTaller()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',150,100))
->integer($image->width())->isEqualTo(150)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(150)
->variable($image->sizer()->resizeToHeight())->isEqualTo(75)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testLandscapeWhenImageIsShorter()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',300,75))
->integer($image->width())->isEqualTo(150)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(150)
->variable($image->sizer()->resizeToHeight())->isEqualTo(75)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testLandscapeWithSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',300,75))
->integer($image->width())->isEqualTo(75)
->integer($image->height())->isEqualTo(75)
->variable($image->sizer()->resizeToWidth())->isEqualTo(75)
->variable($image->sizer()->resizeToHeight())->isEqualTo(75)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testLandscapeWithPortraitImage()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',200,100))
->integer($image->width())->isEqualTo(50)
->integer($image->height())->isEqualTo(100)
->variable($image->sizer()->resizeToWidth())->isEqualTo(50)
->variable($image->sizer()->resizeToHeight())->isEqualTo(100)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testWithSmallSquareImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x200.jpg',300,300))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testWithSmallLandscapeImage()
{
$this
->given($image = $this->image(__DIR__.'/../200x100.jpg',300,300))
->integer($image->width())->isEqualTo(300)
->integer($image->height())->isEqualTo(150)
->variable($image->sizer()->resizeToWidth())->isEqualTo(300)
->variable($image->sizer()->resizeToHeight())->isEqualTo(150)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
public function testWithSmallPortraitImage()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg',300,300))
->integer($image->width())->isEqualTo(150)
->integer($image->height())->isEqualTo(300)
->variable($image->sizer()->resizeToWidth())->isEqualTo(150)
->variable($image->sizer()->resizeToHeight())->isEqualTo(300)
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
protected function image(string $path, int $width, int $height)
{
$driver = new MockDriver();
return $driver->image($path, new SizerUnderTest($width, $height));
}
}

View file

@ -1,36 +0,0 @@
<?php
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\tests\units\Sizers;
use atoum;
use ByJoby\ImageTransform\Sizers\Original as SizerUnderTest;
use ByJoby\ImageTransform\tests\units\mock\MockDriver;
class Original extends atoum
{
public function testRotation()
{
$this
->given($image = $this->image(__DIR__.'/../100x200.jpg'))
->integer($image->width())->isEqualTo(100)
->integer($image->height())->isEqualTo(200)
->variable($image->sizer()->resizeToWidth())->isNull()
->variable($image->sizer()->resizeToHeight())->isNull()
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
->given($image->rotate())
->integer($image->width())->isEqualTo(200)
->integer($image->height())->isEqualTo(100)
->variable($image->sizer()->resizeToWidth())->isNull()
->variable($image->sizer()->resizeToHeight())->isNull()
->variable($image->sizer()->cropToWidth())->isNull()
->variable($image->sizer()->cropToHeight())->isNull()
;
}
protected function image(string $path)
{
$driver = new MockDriver();
return $driver->image($path, new SizerUnderTest());
}
}

View file

@ -1,14 +0,0 @@
<?php
/* image-transform | https://github.com/jobyone/image-transform | MIT License */
namespace ByJoby\ImageTransform\tests\units\mock;
use ByJoby\ImageTransform\Drivers\AbstractDriver;
use ByJoby\ImageTransform\Image;
class MockDriver extends AbstractDriver
{
protected function doSave(Image $image, string $filename)
{
//does nothing
}
}