Skip to content

Commit

Permalink
quality range conversion, more tests, better regex
Browse files Browse the repository at this point in the history
  • Loading branch information
Gappa committed Jun 26, 2023
1 parent fb29661 commit 87d4d31
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 12 deletions.
57 changes: 52 additions & 5 deletions src/ResizerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Nelson\Resizer;

use Exception;
use Nelson\Resizer\DI\ResizerConfigDTO;
use Nette\SmartObject;

Expand Down Expand Up @@ -148,11 +149,8 @@ public function getOptions(?int $quality = null): array
{

if ($quality !== null) {
$qualityPng = (int) round($quality / 10);

if ($qualityPng > 9) {
$qualityPng = 9;
}
/** @var int<0, 9> $qualityPng */
$qualityPng = (int) round($this->remapRange($quality, 0, 100, 0, 9));
}

return [
Expand All @@ -170,4 +168,53 @@ public function getSupportedFormats(): array
return $this->supportedFormats;
}


/**
* @see https://stackoverflow.com/a/36244586/2458557
*/
private function remapRange(
int $intValue,
int $oMin,
int $oMax,
int $nMin,
int $nMax
): float {
// Range check
if ($oMin === $oMax) {
throw new Exception('Warning: Zero input range');
}

if ($nMin === $nMax) {
throw new Exception('Warning: Zero output range');
}

// Check reversed input range
$bReverseInput = false;
$intOldMin = min($oMin, $oMax);
$intOldMax = max($oMin, $oMax);
if ($intOldMin !== $oMin) {
$bReverseInput = true;
}

// Check reversed output range
$bReverseOutput = false;
$intNewMin = min($nMin, $nMax);
$intNewMax = max($nMin, $nMax);
if ($intNewMin !== $nMin) {
$bReverseOutput = true;
}

$fRatio = ($intValue - $intOldMin) * ($intNewMax - $intNewMin) / ($intOldMax - $intOldMin);
if ($bReverseInput) {
$fRatio = ($intOldMax - $intValue) * ($intNewMax - $intNewMin) / ($intOldMax - $intOldMin);
}

$fResult = $fRatio + $intNewMin;
if ($bReverseOutput) {
$fResult = $intNewMax - $fRatio;
}

return $fResult;
}

}
4 changes: 2 additions & 2 deletions src/ResizerParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function hasWidth(): bool
}


/** @return int<0,100>|null */
/** @return positive-int|null */
public function getHeight(): ?int
{
return $this->height;
Expand Down Expand Up @@ -105,7 +105,7 @@ public function hasNoDimensions(): bool
}


/** @return positive-int|null */
/** @return int<0, 100>|null */
public function getQuality(): ?int
{
return $this->quality;
Expand Down
10 changes: 5 additions & 5 deletions src/ResizerParamsParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class ResizerParamsParser
private const PATTERN = '~
^(?:auto| # use the image as-is, only compress/convert
(?:(ifresize)-)? # ifresize modifier
([lcr]?)(\d*) # width modifer and dimension
([lcr]?)([1-9][0-9]*)? # width modifer and dimension
x # divider
([tcb]?)(\d*) # height modifier and dimension
([tcb]?)([1-9][0-9]*)? # height modifier and dimension
(!?) # force dimensions, disregard aspect ratio
([+-]?[0-9]*) # horizontal margin, unused
([+-]?[0-9]*) # vertical margin, unused
(?:-hm([+-]?[0-9]*))? # horizontal margin, unused
(?:-vm([+-]?[0-9]*))? # vertical margin, unused
(?:-q([0-9][0-9]?|100))? # quality, 0-100
)$
~x';
Expand Down Expand Up @@ -82,7 +82,7 @@ private function parseNumericValueToIntOrNull(string $value): ?int
if (is_numeric($value)) {
$int = (int) $value;

if ($int >= 0) {
if ($int > 0) {
return $int;
}
}
Expand Down
116 changes: 116 additions & 0 deletions tests/ResizerParamsParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,101 @@ public function testQuality4(): void
}


public function testMargin1(): void
{
$expected = new ResizerParams(
false,
null,
null,
false,
'-100',
null,
100,
200,
null,
);

$actual = $this->parse('100x200-hm-100');
$this->assertEquals($expected, $actual);
}


public function testMargin2(): void
{
$expected = new ResizerParams(
false,
null,
null,
false,
'+100',
null,
100,
200,
null,
);

$actual = $this->parse('100x200-hm+100');
$this->assertEquals($expected, $actual);
}


public function testMargin3(): void
{
$expected = new ResizerParams(
false,
null,
null,
false,
null,
'-50',
100,
200,
null,
);

$actual = $this->parse('100x200-vm-50');
$this->assertEquals($expected, $actual);
}


public function testMargin4(): void
{
$expected = new ResizerParams(
false,
null,
null,
false,
null,
'+50',
100,
200,
null,
);

$actual = $this->parse('100x200-vm+50');
$this->assertEquals($expected, $actual);
}


public function testMargin5(): void
{
$expected = new ResizerParams(
false,
null,
null,
false,
'-100',
'+50',
100,
200,
null,
);

$actual = $this->parse('100x200-hm-100-vm+50');
$this->assertEquals($expected, $actual);
}


public function testWrongKeyword1(): void
{
$this->expectException(CouldNotParseResizerParamsException::class);
Expand Down Expand Up @@ -344,6 +439,27 @@ public function testEmptyString(): void
}


public function testEmptyZeroDimensions1(): void
{
$this->expectException(CouldNotParseResizerParamsException::class);
$this->parse('0x');
}


public function testEmptyZeroDimensions2(): void
{
$this->expectException(CouldNotParseResizerParamsException::class);
$this->parse('x0');
}


public function testEmptyZeroDimensions3(): void
{
$this->expectException(CouldNotParseResizerParamsException::class);
$this->parse('0x0');
}


public function testEmptyNull(): void
{
$this->expectException(CouldNotParseResizerParamsException::class);
Expand Down

0 comments on commit 87d4d31

Please sign in to comment.