Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  Modifiy srcset order: 1x resolutions first
  Rename highres config option
  Create php.yml
  • Loading branch information
martinheise committed Feb 24, 2025
2 parents 0e7647a + 0cc54cb commit 7a5518a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 26 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: PHP Composer

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
run: composer install --prefer-dist --no-progress

# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md

# - name: Run test suite
# run: composer run-script test
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ Lower values mean more generated files, better matching the particular user cond
Set a limit on the number of renditions generated, has precedence of `sizediff`. With low `sizediff` values and large images this will assure that you don’t end up with vast amount of images generated.
#### retinalevel
#### highres
Set to either `2` or `3`adds up extra levels for high resolution screens. If e.g. the maximum calculated image width is 1200px, also renditions for 2400px are created.
Set to either `2` or `3` adds up extra levels for high resolution screens. If e.g. the maximum calculated image width is 1200px, also renditions for 2400px (or even 3600px) are created.
#### rendersizes
Expand Down
33 changes: 23 additions & 10 deletions src/Data/RenderConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ class RenderConfig
protected string $sizes;
protected int $maxsteps;
protected int $sizediff;
protected int $retinalevel;
protected int $highres;
protected array $rendersizes;

/**
* @param $sizes string image size definition, possibly containing media queries, as given in img sizes attribute, e.g. "(max-width: 1000px) 100vw, 1000px"
* @param $maxsteps int maximum number of image variants to create
* @param $sizediff int desired filesize difference (in bytes) between variants – will not be considered exactly but is a rough goal
* @param $retinalevel int number of levels for retina resolutions (1, 2, 3)
* @param $highres int levels for pixel density (1, 2 or 3)
* @param $rendersizes int[] optionally set fixed sizes (in px) to generate – the other params for auto calculation will be ignored
*/
public function __construct(string $sizes, int $maxsteps = 10, int $sizediff = 50000, int $retinalevel = 1, array $rendersizes = [])
public function __construct (string $sizes, int $maxsteps = 10, int $sizediff = 50000, int $highres = 1, array $rendersizes = [])
{
$this->sizes = $sizes;
$this->maxsteps = $maxsteps;
$this->sizediff = $sizediff;
$this->retinalevel = $retinalevel;
$this->highres = $highres;
$this->rendersizes = $rendersizes;
$this->validateValues();
}
Expand All @@ -42,7 +42,7 @@ private function validateValues(): void
} else {
$this->sizediff = max($this->sizediff, 20000);
}
$this->retinalevel = max(min($this->retinalevel, 3), 1);
$this->highres = max(min($this->highres, 3), 1);
foreach ($this->rendersizes as $size) {
if (!is_numeric($size)) {
$this->rendersizes = [];
Expand Down Expand Up @@ -122,21 +122,34 @@ public function setSizediff(int $sizediff): void
$this->validateValues();
}

public function getHighres(): int
{
return $this->highres;
}

/**
* @return int
* @param int $highres
*/
public function setHighres(int $highres): void
{
$this->highres = $highres;
$this->validateValues();
}

/**
* @deprecated use getHighres()
*/
public function getRetinalevel(): int
{
return $this->retinalevel;
return $this->getHighres();
}

/**
* @param int $retinalevel
* @deprecated use setHighres()
*/
public function setRetinalevel(int $retinalevel): void
{
$this->retinalevel = $retinalevel;
$this->validateValues();
$this->setHighres($retinalevel);
}

/**
Expand Down
8 changes: 5 additions & 3 deletions src/ImageResizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public function getVariants(ImageData $srcimage, RenderConfig $config): array
$maxwidth = max(array_values($sizevalues));

// prevent upscaling
// ToDo: check logic, especially for retinaretina will still be upscaled this way!
// ToDo: check logic, especially for highreshighres will still be upscaled this way!
$maxwidth = min($maxwidth, $srcimage->getWidth());
if ($maxwidth < $minwidth) {
$minwidth = $maxwidth;
Expand All @@ -105,12 +105,14 @@ public function getVariants(ImageData $srcimage, RenderConfig $config): array
}

$variants = [];
// 1x resolutions first – can be used for meaningful src attribute
$variants = array_merge($variants, $this->processVariants($srcimage, $maxwidth, $minwidth, $ratio, $config->getSizediff(), $config->getMaxsteps(), $config->getRendersizes()));
// additional highres renditions
if (count($config->getRendersizes()) == 0) {
for ($r = $config->getRetinalevel(); $r > 1; $r--) {
for ($r = $config->getHighres(); $r > 1; $r--) {
$variants = array_merge($variants, $this->processVariants($srcimage, $maxwidth * $r, $maxwidth * ($r - 1) * 1.2, $ratio, $config->getSizediff(), $config->getMaxsteps()));
}
}
$variants = array_merge($variants, $this->processVariants($srcimage, $maxwidth, $minwidth, $ratio, $config->getSizediff(), $config->getMaxsteps(), $config->getRendersizes()));

return $variants;
}
Expand Down
22 changes: 11 additions & 11 deletions tests/ImageResizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ public function testSimple()
$this->assertResultWidths([2400], $variants); // max viewport
}

public function testSimpleRetina()
public function testSimpleHighres()
{
$config = new RenderConfig("100vw", 5, 1000000, 2, []);
$variants = $this->resizer->getVariants($this->images['200'], $config);
$this->assertResultWidths([400, 200], $variants); // kept original size
$this->assertResultWidths([200, 400], $variants); // kept original size
$variants = $this->resizer->getVariants($this->images['4800'], $config);
$this->assertResultWidths([4800, 2400], $variants); // max viewport
$this->assertResultWidths([2400, 4800], $variants); // max viewport
}

public function testRemValue()
Expand Down Expand Up @@ -88,16 +88,16 @@ public function testSizeDiff()
$this->assertResultWidths([2400, 1939, 1449, 900], $variants); // max viewport
}

public function testSizeDiffRetina()
public function testSizeDiffHighres()
{
$config = new RenderConfig("100vw", 10, 64000, 2, []);
$variants = $this->resizer->getVariants($this->images['200'], $config);
$this->assertResultWidths([400, 200], $variants); // kept original size
$this->assertResultWidths([200, 400], $variants); // kept original size
$variants = $this->resizer->getVariants($this->images['4800'], $config);
$this->assertEquals(10, count($variants));
// first step for 2x should be: 4800px -> filesize: 1024000 => 10 (max)steps, limited by next level
// first step should be: 2400px -> filesize: 256000 => 4 steps
$this->assertResultWidths([4800, 4437, 4067, 3688, 3299, 2897, 2400, 1939, 1449, 900], $variants); // max viewport
// first step for 2x should be: 4800px -> filesize: 1024000 => 10 (max)steps, limited by 1x level
$this->assertResultWidths([2400, 1939, 1449, 900, 4800, 4437, 4067, 3688, 3299, 2897], $variants); // max viewport
}

public function testMaxSteps()
Expand All @@ -110,15 +110,15 @@ public function testMaxSteps()
$this->assertResultWidths([2400, 1939, 1449, 900], $variants); // max viewport
}

public function testMaxStepsRetina()
public function testMaxStepsHighres()
{
$config = new RenderConfig("100vw", 4, 1000, 2, []);
$variants = $this->resizer->getVariants($this->images['200'], $config);
$this->assertResultWidths([400, 200], $variants); // kept original size
$this->assertResultWidths([200, 400], $variants); // kept original size
$variants = $this->resizer->getVariants($this->images['4800'], $config);
$this->assertEquals(7, count($variants));
// retina resolutions: 2x the regular ones, but stopping before reaching 1x width, so fewer values
$this->assertResultWidths([4800, 3878, 2897, 2400, 1939, 1449, 900], $variants); // max viewport
// highres resolutions: 2x the regular ones, but stopping before reaching 1x width, so fewer values
$this->assertResultWidths([2400, 1939, 1449, 900, 4800, 3878, 2897], $variants); // max viewport
}

public function testBreakpoints()
Expand Down

0 comments on commit 7a5518a

Please sign in to comment.