mirror of
https://github.com/Intervention/image.git
synced 2025-08-27 15:50:09 +02:00
Geometry refactoring
This commit is contained in:
@@ -11,7 +11,7 @@ class Resizer
|
|||||||
*
|
*
|
||||||
* @var SizeInterface
|
* @var SizeInterface
|
||||||
*/
|
*/
|
||||||
protected $size;
|
protected $original;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target size
|
* Target size
|
||||||
@@ -20,20 +20,20 @@ class Resizer
|
|||||||
*/
|
*/
|
||||||
protected $target;
|
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);
|
$this->target = new Size(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromSize(SizeInterface $size): self
|
protected function copyOriginal(): SizeInterface
|
||||||
{
|
{
|
||||||
return new self($size);
|
return new Size($this->original->getWidth(), $this->original->getHeight());
|
||||||
}
|
|
||||||
|
|
||||||
public function getSize(): SizeInterface
|
|
||||||
{
|
|
||||||
return $this->size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function hasTargetWidth(): bool
|
protected function hasTargetWidth(): bool
|
||||||
@@ -81,14 +81,32 @@ class Resizer
|
|||||||
|
|
||||||
public function setTargetSize(SizeInterface $size): self
|
public function setTargetSize(SizeInterface $size): self
|
||||||
{
|
{
|
||||||
$this->target = $size;
|
$this->target = new Size($size->getWidth(), $size->getHeight());
|
||||||
|
|
||||||
return $this;
|
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
|
public function resize(): SizeInterface
|
||||||
{
|
{
|
||||||
$resized = clone $this->size;
|
$resized = $this->copyOriginal();
|
||||||
|
|
||||||
if ($this->hasTargetWidth()) {
|
if ($this->hasTargetWidth()) {
|
||||||
$resized->setWidth($this->target->getWidth());
|
$resized->setWidth($this->target->getWidth());
|
||||||
@@ -103,92 +121,82 @@ class Resizer
|
|||||||
|
|
||||||
public function resizeDown(): SizeInterface
|
public function resizeDown(): SizeInterface
|
||||||
{
|
{
|
||||||
|
$resized = $this->copyOriginal();
|
||||||
|
|
||||||
if ($this->hasTargetWidth()) {
|
if ($this->hasTargetWidth()) {
|
||||||
$this->target->setWidth(
|
$resized->setWidth(
|
||||||
min($this->target->getWidth(), $this->size->getWidth())
|
min($this->target->getWidth(), $this->original->getWidth())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->hasTargetHeight()) {
|
if ($this->hasTargetHeight()) {
|
||||||
$this->target->setHeight(
|
$resized->setHeight(
|
||||||
min($this->target->getHeight(), $this->size->getHeight())
|
min($this->target->getHeight(), $this->original->getHeight())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->resize();
|
return $resized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scale(): SizeInterface
|
public function scale(): SizeInterface
|
||||||
{
|
{
|
||||||
|
$resized = $this->copyOriginal();
|
||||||
|
|
||||||
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
|
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
|
||||||
$this->target->setWidth(min(
|
$resized->setWidth(min(
|
||||||
$this->getProportionalWidth(),
|
$this->getProportionalWidth(),
|
||||||
$this->target->getWidth()
|
$this->target->getWidth()
|
||||||
));
|
));
|
||||||
$this->target->setHeight(min(
|
$resized->setHeight(min(
|
||||||
$this->getProportionalHeight(),
|
$this->getProportionalHeight(),
|
||||||
$this->target->getHeight()
|
$this->target->getHeight()
|
||||||
));
|
));
|
||||||
} elseif ($this->hasTargetWidth()) {
|
} elseif ($this->hasTargetWidth()) {
|
||||||
$this->target->setHeight($this->getProportionalHeight());
|
$resized->setWidth($this->target->getWidth());
|
||||||
|
$resized->setHeight($this->getProportionalHeight());
|
||||||
} elseif ($this->hasTargetHeight()) {
|
} 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
|
public function scaleDown(): SizeInterface
|
||||||
{
|
{
|
||||||
|
$resized = $this->copyOriginal();
|
||||||
|
|
||||||
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
|
if ($this->hasTargetWidth() && $this->hasTargetHeight()) {
|
||||||
$this->target->setWidth(min(
|
$resized->setWidth(min(
|
||||||
$this->getProportionalWidth(),
|
$this->getProportionalWidth(),
|
||||||
$this->target->getWidth(),
|
$this->target->getWidth(),
|
||||||
$this->size->getWidth()
|
$this->original->getWidth()
|
||||||
));
|
));
|
||||||
$this->target->setHeight(min(
|
$resized->setHeight(min(
|
||||||
$this->getProportionalHeight(),
|
$this->getProportionalHeight(),
|
||||||
$this->target->getHeight(),
|
$this->target->getHeight(),
|
||||||
$this->size->getHeight()
|
$this->original->getHeight()
|
||||||
));
|
));
|
||||||
} elseif ($this->hasTargetWidth()) {
|
} elseif ($this->hasTargetWidth()) {
|
||||||
$this->target->setWidth(min(
|
$resized->setWidth(min(
|
||||||
$this->target->getWidth(),
|
$this->target->getWidth(),
|
||||||
$this->size->getWidth()
|
$this->original->getWidth()
|
||||||
));
|
));
|
||||||
$this->target->setHeight(min(
|
$resized->setHeight(min(
|
||||||
$this->getProportionalHeight(),
|
$this->getProportionalHeight(),
|
||||||
$this->size->getHeight()
|
$this->original->getHeight()
|
||||||
));
|
));
|
||||||
} elseif ($this->hasTargetHeight()) {
|
} elseif ($this->hasTargetHeight()) {
|
||||||
$this->target->setWidth(min(
|
$resized->setWidth(min(
|
||||||
$this->getProportionalWidth(),
|
$this->getProportionalWidth(),
|
||||||
$this->size->getWidth()
|
$this->original->getWidth()
|
||||||
));
|
));
|
||||||
$this->target->setHeight(min(
|
$resized->setHeight(min(
|
||||||
$this->target->getHeight(),
|
$this->target->getHeight(),
|
||||||
$this->size->getHeight()
|
$this->original->getHeight()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->resize();
|
return $resized;
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,13 @@ class Size implements SizeInterface
|
|||||||
return $this->pivot;
|
return $this->pivot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPivot(PointInterface $pivot): self
|
||||||
|
{
|
||||||
|
$this->pivot = $pivot;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setWidth(int $width): SizeInterface
|
public function setWidth(int $width): SizeInterface
|
||||||
{
|
{
|
||||||
$this->width = $width;
|
$this->width = $width;
|
||||||
|
@@ -8,6 +8,13 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class ResizerTest extends 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()
|
public function testSetTargetSizeByArray()
|
||||||
{
|
{
|
||||||
$resizer = new Resizer(new Size(300, 200));
|
$resizer = new Resizer(new Size(300, 200));
|
||||||
@@ -63,22 +70,16 @@ class ResizerTest extends TestCase
|
|||||||
$resizer = new Resizer($size);
|
$resizer = new Resizer($size);
|
||||||
$resizer->width(150);
|
$resizer->width(150);
|
||||||
$result = $resizer->resize();
|
$result = $resizer->resize();
|
||||||
$original = $resizer->getSize();
|
|
||||||
$this->assertEquals(150, $result->getWidth());
|
$this->assertEquals(150, $result->getWidth());
|
||||||
$this->assertEquals(200, $result->getHeight());
|
$this->assertEquals(200, $result->getHeight());
|
||||||
$this->assertEquals(300, $original->getWidth());
|
|
||||||
$this->assertEquals(200, $original->getHeight());
|
|
||||||
|
|
||||||
$size = new Size(300, 200);
|
$size = new Size(300, 200);
|
||||||
$resizer = new Resizer($size);
|
$resizer = new Resizer($size);
|
||||||
$resizer->width(20);
|
$resizer->width(20);
|
||||||
$resizer->height(10);
|
$resizer->height(10);
|
||||||
$result = $resizer->resize();
|
$result = $resizer->resize();
|
||||||
$original = $resizer->getSize();
|
|
||||||
$this->assertEquals(20, $result->getWidth());
|
$this->assertEquals(20, $result->getWidth());
|
||||||
$this->assertEquals(10, $result->getHeight());
|
$this->assertEquals(10, $result->getHeight());
|
||||||
$this->assertEquals(300, $original->getWidth());
|
|
||||||
$this->assertEquals(200, $original->getHeight());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testResizeDown()
|
public function testResizeDown()
|
||||||
@@ -367,4 +368,5 @@ class ResizerTest extends TestCase
|
|||||||
$this->assertEquals(13, $result->getWidth());
|
$this->assertEquals(13, $result->getWidth());
|
||||||
$this->assertEquals(10, $result->getHeight());
|
$this->assertEquals(10, $result->getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -143,4 +143,47 @@ class SizeTest extends TestCase
|
|||||||
|
|
||||||
$this->assertInstanceOf(Size::class, $result);
|
$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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user