1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-27 07:44:30 +02:00

Geometry refactoring

This commit is contained in:
Oliver Vogel
2021-11-07 11:37:42 +00:00
parent 304d158fb0
commit 9ac8e765c2
4 changed files with 119 additions and 59 deletions

View File

@@ -11,7 +11,7 @@ class Resizer
*
* @var SizeInterface
*/
protected $size;
protected $original;
/**
* Target size
@@ -20,20 +20,20 @@ class Resizer
*/
protected $target;
public function __construct(SizeInterface $size)
/**
* Create new instance
*
* @param SizeInterface $size
*/
public function __construct(SizeInterface $original)
{
$this->size = $size;
$this->original = $original;
$this->target = new Size(0, 0);
}
public static function fromSize(SizeInterface $size): self
protected function copyOriginal(): SizeInterface
{
return new self($size);
}
public function getSize(): SizeInterface
{
return $this->size;
return new Size($this->original->getWidth(), $this->original->getHeight());
}
protected function hasTargetWidth(): bool
@@ -81,14 +81,32 @@ class Resizer
public function setTargetSize(SizeInterface $size): self
{
$this->target = $size;
$this->target = new Size($size->getWidth(), $size->getHeight());
return $this;
}
protected function getProportionalWidth(): int
{
if (! $this->hasTargetHeight()) {
return $this->original->getWidth();
}
return (int) round($this->target->getHeight() * $this->original->getAspectRatio());
}
protected function getProportionalHeight(): int
{
if (! $this->hasTargetWidth()) {
return $this->original->getHeight();
}
return (int) round($this->target->getWidth() / $this->original->getAspectRatio());
}
public function resize(): SizeInterface
{
$resized = clone $this->size;
$resized = $this->copyOriginal();
if ($this->hasTargetWidth()) {
$resized->setWidth($this->target->getWidth());
@@ -103,92 +121,82 @@ class Resizer
public function resizeDown(): SizeInterface
{
$resized = $this->copyOriginal();
if ($this->hasTargetWidth()) {
$this->target->setWidth(
min($this->target->getWidth(), $this->size->getWidth())
$resized->setWidth(
min($this->target->getWidth(), $this->original->getWidth())
);
}
if ($this->hasTargetHeight()) {
$this->target->setHeight(
min($this->target->getHeight(), $this->size->getHeight())
$resized->setHeight(
min($this->target->getHeight(), $this->original->getHeight())
);
}
return $this->resize();
return $resized;
}
public function scale(): SizeInterface
{
$resized = $this->copyOriginal();
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
$this->target->setWidth(min(
$resized->setWidth(min(
$this->getProportionalWidth(),
$this->target->getWidth()
));
$this->target->setHeight(min(
$resized->setHeight(min(
$this->getProportionalHeight(),
$this->target->getHeight()
));
} elseif ($this->hasTargetWidth()) {
$this->target->setHeight($this->getProportionalHeight());
$resized->setWidth($this->target->getWidth());
$resized->setHeight($this->getProportionalHeight());
} elseif ($this->hasTargetHeight()) {
$this->target->setWidth($this->getProportionalWidth());
$resized->setWidth($this->getProportionalWidth());
$resized->setHeight($this->target->getHeight());
}
return $this->resize();
return $resized;
}
public function scaleDown(): SizeInterface
{
$resized = $this->copyOriginal();
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
$this->target->setWidth(min(
$resized->setWidth(min(
$this->getProportionalWidth(),
$this->target->getWidth(),
$this->size->getWidth()
$this->original->getWidth()
));
$this->target->setHeight(min(
$resized->setHeight(min(
$this->getProportionalHeight(),
$this->target->getHeight(),
$this->size->getHeight()
$this->original->getHeight()
));
} elseif ($this->hasTargetWidth()) {
$this->target->setWidth(min(
$resized->setWidth(min(
$this->target->getWidth(),
$this->size->getWidth()
$this->original->getWidth()
));
$this->target->setHeight(min(
$resized->setHeight(min(
$this->getProportionalHeight(),
$this->size->getHeight()
$this->original->getHeight()
));
} elseif ($this->hasTargetHeight()) {
$this->target->setWidth(min(
$resized->setWidth(min(
$this->getProportionalWidth(),
$this->size->getWidth()
$this->original->getWidth()
));
$this->target->setHeight(min(
$resized->setHeight(min(
$this->target->getHeight(),
$this->size->getHeight()
$this->original->getHeight()
));
}
return $this->resize();
}
protected function getProportionalWidth(): int
{
if (! $this->hasTargetHeight()) {
return $this->size->getWidth();
}
return (int) round($this->target->getHeight() * $this->size->getAspectRatio());
}
protected function getProportionalHeight(): int
{
if (! $this->hasTargetWidth()) {
return $this->size->getHeight();
}
return (int) round($this->target->getWidth() / $this->size->getAspectRatio());
return $resized;
}
}

View File

@@ -38,6 +38,13 @@ class Size implements SizeInterface
return $this->pivot;
}
public function setPivot(PointInterface $pivot): self
{
$this->pivot = $pivot;
return $this;
}
public function setWidth(int $width): SizeInterface
{
$this->width = $width;

View File

@@ -8,6 +8,13 @@ use PHPUnit\Framework\TestCase;
class ResizerTest extends TestCase
{
public function testConstructor(): void
{
$size = new Size(300, 200);
$resizer = new Resizer($size);
$this->assertInstanceOf(Resizer::class, $resizer);
}
public function testSetTargetSizeByArray()
{
$resizer = new Resizer(new Size(300, 200));
@@ -63,22 +70,16 @@ class ResizerTest extends TestCase
$resizer = new Resizer($size);
$resizer->width(150);
$result = $resizer->resize();
$original = $resizer->getSize();
$this->assertEquals(150, $result->getWidth());
$this->assertEquals(200, $result->getHeight());
$this->assertEquals(300, $original->getWidth());
$this->assertEquals(200, $original->getHeight());
$size = new Size(300, 200);
$resizer = new Resizer($size);
$resizer->width(20);
$resizer->height(10);
$result = $resizer->resize();
$original = $resizer->getSize();
$this->assertEquals(20, $result->getWidth());
$this->assertEquals(10, $result->getHeight());
$this->assertEquals(300, $original->getWidth());
$this->assertEquals(200, $original->getHeight());
}
public function testResizeDown()
@@ -367,4 +368,5 @@ class ResizerTest extends TestCase
$this->assertEquals(13, $result->getWidth());
$this->assertEquals(10, $result->getHeight());
}
}

View File

@@ -143,4 +143,47 @@ class SizeTest extends TestCase
$this->assertInstanceOf(Size::class, $result);
}
public function testRelativePosition(): void
{
$container = new Size(800, 600);
$input = new Size(200, 100);
$container->align('top-left');
$input->align('top-left');
$pos = $container->relativePosition($input);
$this->assertEquals(0, $pos->getX());
$this->assertEquals(0, $pos->getY());
$container = new Size(800, 600);
$input = new Size(200, 100);
$container->align('center');
$input->align('top-left');
$pos = $container->relativePosition($input);
$this->assertEquals(400, $pos->getX());
$this->assertEquals(300, $pos->getY());
$container = new Size(800, 600);
$input = new Size(200, 100);
$container->align('bottom-right');
$input->align('top-right');
$pos = $container->relativePosition($input);
$this->assertEquals(600, $pos->getX());
$this->assertEquals(600, $pos->getY());
$container = new Size(800, 600);
$input = new Size(200, 100);
$container->align('center');
$input->align('center');
$pos = $container->relativePosition($input);
$this->assertEquals(300, $pos->getX());
$this->assertEquals(250, $pos->getY());
$container = new Size(100, 200);
$input = new Size(100, 100);
$container->align('center');
$input->align('center');
$pos = $container->relativePosition($input);
$this->assertEquals(0, $pos->getX());
$this->assertEquals(50, $pos->getY());
}
}