Skip to content

Commit

Permalink
Merge pull request #216 from 0xb4lint/fix-factory-options
Browse files Browse the repository at this point in the history
Fix OptimizerChainFactory's missing config processor
  • Loading branch information
timvandijck committed May 3, 2024
2 parents 02e2717 + 2e73bef commit a639919
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 35 deletions.
84 changes: 50 additions & 34 deletions src/OptimizerChainFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,75 @@ class OptimizerChainFactory
{
public static function create(array $config = []): OptimizerChain
{
$jpegQuality = '--max=85';
$pngQuality = '--quality=85';
$webpQuality = '-q 80';
$avifQuality = '-a cq-level=23';
if (isset($config['quality'])) {
$jpegQuality = '--max='.$config['quality'];
$pngQuality = '--quality='.$config['quality'];
$webpQuality = '-q '.$config['quality'];
$avifQuality = '-a cq-level='.round(63 - $config['quality'] * 0.63);
$optimizers = self::getOptimizers($config);
$optimizerChain = new OptimizerChain();

foreach ($optimizers as $optimizer => $optimizerConfig) {
$optimizerChain->addOptimizer(new $optimizer($optimizerConfig));
}

return (new OptimizerChain())
->addOptimizer(new Jpegoptim([
$jpegQuality,
return $optimizerChain;
}

/**
* @return array<class-string, array>
*/
private static function getOptimizers(array $config): array
{
if (self::configHasOptimizer($config)) {
return $config;
}

return [
Jpegoptim::class => [
'-m' . ($config['quality'] ?? 85),
'--force',
'--strip-all',
'--all-progressive',
]))

->addOptimizer(new Pngquant([
$pngQuality,
],
Pngquant::class => [
'--quality=' . ($config['quality'] ?? 85),
'--force',
'--skip-if-larger',
]))

->addOptimizer(new Optipng([
],
Optipng::class => [
'-i0',
'-o2',
'-quiet',
]))

->addOptimizer(new Svgo([
'--config=svgo.config.js',
]))

->addOptimizer(new Gifsicle([
],
Svgo::class => [],
Gifsicle::class => [
'-b',
'-O3',
]))
->addOptimizer(new Cwebp([
$webpQuality,
],
Cwebp::class => [
'-m 6',
'-pass 10',
'-mt',
]))
->addOptimizer(new Avifenc([
$avifQuality,
'-q ' . ($config['quality'] ?? 90),
],
Avifenc::class => [
'-a cq-level=' . (isset($config['quality']) ? round(63 - $config['quality'] * 0.63) : 23),
'-j all',
'--min 0',
'--max 63',
'--minalpha 0',
'--maxalpha 63',
'-a end-usage=q',
'-a tune=ssim',
]));
],
];
}

private static function configHasOptimizer(array $config): bool
{
return (bool)array_diff_key($config, [
Jpegoptim::class,
Pngquant::class,
Optipng::class,
Svgo::class,
Gifsicle::class,
Cwebp::class,
Avifenc::class,
]);
}
}
49 changes: 48 additions & 1 deletion tests/OptimizerChainFactoryTest.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,69 @@
<?php

use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertFileEquals;

use Spatie\ImageOptimizer\Optimizer;
use Spatie\ImageOptimizer\OptimizerChainFactory;
use Spatie\ImageOptimizer\Optimizers\Avifenc;
use Spatie\ImageOptimizer\Optimizers\Cwebp;
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;
use Spatie\ImageOptimizer\Optimizers\Optipng;
use Spatie\ImageOptimizer\Optimizers\Pngquant;

use Spatie\ImageOptimizer\Optimizers\Svgo;

beforeEach(function () {
$this->optimizerChain = OptimizerChainFactory::create()
->useLogger($this->log);
});

it('can use config', function () {
$this->optimizerChain = OptimizerChainFactory::create([
Jpegoptim::class => ['--foo'],
Pngquant::class => ['--foo'],
Optipng::class => ['--foo'],
Svgo::class => ['--foo'],
Gifsicle::class => ['--foo'],
Cwebp::class => ['--foo'],
Avifenc::class => ['--foo'],
])
->useLogger($this->log);

assertEquals(
[
new Jpegoptim(['--foo']),
new Pngquant(['--foo']),
new Optipng(['--foo']),
new Svgo(['--foo']),
new Gifsicle(['--foo']),
new Cwebp(['--foo']),
new Avifenc(['--foo']),
],
$this->optimizerChain->getOptimizers()
);
});

it('can use default config', function () {
assertEquals(
[
Jpegoptim::class,
Pngquant::class,
Optipng::class,
Svgo::class,
Gifsicle::class,
Cwebp::class,
Avifenc::class,
],
array_map(
function (Optimizer $optimizer) {
return get_class($optimizer);
},
$this->optimizerChain->getOptimizers()
)
);
});

it('can optimize a jpg', function () {
$tempFilePath = getTempFilePath('image.jpg');

Expand Down

0 comments on commit a639919

Please sign in to comment.