One Hat Cyber Team
Your IP:
216.73.216.176
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
thread-self
/
root
/
proc
/
self
/
cwd
/
Edit File:
image-optimizer.tar
src/Optimizer.php 0000644 00000002063 15111676173 0010037 0 ustar 00 <?php namespace Spatie\ImageOptimizer; interface Optimizer { /** * Returns the name of the binary to be executed. * * @return string */ public function binaryName(): string; /** * Determines if the given image can be handled by the optimizer. * * @param \Spatie\ImageOptimizer\Image $image * * @return bool */ public function canHandle(Image $image): bool; /** * Set the path to the image that should be optimized. * * @param string $imagePath * * @return $this */ public function setImagePath(string $imagePath); /** * Set the options the optimizer should use. * * @param array $options * * @return $this */ public function setOptions(array $options = []); /** * Get the command that should be executed. * * @return string */ public function getCommand(): string; /** * Get the temporary file's path. * * @return null|string */ public function getTmpPath(): ?string; } src/OptimizerChain.php 0000644 00000005266 15111676173 0011012 0 ustar 00 <?php namespace Spatie\ImageOptimizer; use Psr\Log\LoggerInterface; use Symfony\Component\Process\Process; class OptimizerChain { /* @var \Spatie\ImageOptimizer\Optimizer[] */ protected $optimizers = []; /** @var \Psr\Log\LoggerInterface */ protected $logger; /** @var int */ protected $timeout = 60; public function __construct() { $this->useLogger(new DummyLogger()); } public function getOptimizers(): array { return $this->optimizers; } public function addOptimizer(Optimizer $optimizer) { $this->optimizers[] = $optimizer; return $this; } public function setOptimizers(array $optimizers) { $this->optimizers = []; foreach ($optimizers as $optimizer) { $this->addOptimizer($optimizer); } return $this; } /* * Set the amount of seconds each separate optimizer may use. */ public function setTimeout(int $timeoutInSeconds) { $this->timeout = $timeoutInSeconds; return $this; } public function useLogger(LoggerInterface $log) { $this->logger = $log; return $this; } public function optimize(string $pathToImage, string $pathToOutput = null) { if ($pathToOutput) { copy($pathToImage, $pathToOutput); $pathToImage = $pathToOutput; } $image = new Image($pathToImage); $this->logger->info("Start optimizing {$pathToImage}"); foreach ($this->optimizers as $optimizer) { $this->applyOptimizer($optimizer, $image); } } protected function applyOptimizer(Optimizer $optimizer, Image $image) { if (! $optimizer->canHandle($image)) { return; } $optimizerClass = get_class($optimizer); $this->logger->info("Using optimizer: `{$optimizerClass}`"); $optimizer->setImagePath($image->path()); $command = $optimizer->getCommand(); $this->logger->info("Executing `{$command}`"); $process = Process::fromShellCommandline($command); $process ->setTimeout($this->timeout) ->run(); if ( ($tmpPath = $optimizer->getTmpPath()) && file_exists($tmpPath) ) { unlink($tmpPath); } $this->logResult($process); } protected function logResult(Process $process) { if (! $process->isSuccessful()) { $this->logger->error("Process errored with `{$process->getErrorOutput()}`"); return; } $this->logger->info("Process successfully ended with output `{$process->getOutput()}`"); } } src/Optimizers/Optipng.php 0000644 00000000420 15111676173 0011635 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Optipng extends BaseOptimizer { public $binaryName = 'optipng'; public function canHandle(Image $image): bool { return $image->mime() === 'image/png'; } } src/Optimizers/BaseOptimizer.php 0000644 00000002412 15111676174 0012776 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Optimizer; abstract class BaseOptimizer implements Optimizer { public $options = []; public $imagePath = ''; public $binaryPath = ''; public $tmpPath = null; public function __construct($options = []) { $this->setOptions($options); } public function binaryName(): string { return $this->binaryName; } public function setBinaryPath(string $binaryPath) { if (strlen($binaryPath) > 0 && substr($binaryPath, -1) !== DIRECTORY_SEPARATOR) { $binaryPath = $binaryPath.DIRECTORY_SEPARATOR; } $this->binaryPath = $binaryPath; return $this; } public function setImagePath(string $imagePath) { $this->imagePath = $imagePath; return $this; } public function setOptions(array $options = []) { $this->options = $options; return $this; } public function getCommand(): string { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString} ".escapeshellarg($this->imagePath); } public function getTmpPath(): ?string { return $this->tmpPath; } } src/Optimizers/Avifenc.php 0000644 00000002464 15111676174 0011603 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Avifenc extends BaseOptimizer { public $binaryName = 'avifenc'; public $decodeBinaryName = 'avifdec'; public function canHandle(Image $image): bool { if (version_compare(PHP_VERSION, '8.1.0', '<')) { return $image->extension() === 'avif'; } return $image->mime() === 'image/avif'; } public function getCommand(): string { return $this->getDecodeCommand().' && ' .$this->getEncodeCommand(); } protected function getDecodeCommand() { $this->tmpPath = tempnam(sys_get_temp_dir(), 'avifdec').'.png'; $optionString = implode(' ', [ '-j all', '--ignore-icc', '--no-strict', '--png-compress 0', ]); return "\"{$this->binaryPath}{$this->decodeBinaryName}\" {$optionString}" .' '.escapeshellarg($this->imagePath) .' '.escapeshellarg($this->tmpPath); } protected function getEncodeCommand() { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString}" .' '.escapeshellarg($this->tmpPath) .' '.escapeshellarg($this->imagePath); } } src/Optimizers/Pngquant.php 0000644 00000001071 15111676174 0012016 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Pngquant extends BaseOptimizer { public $binaryName = 'pngquant'; public function canHandle(Image $image): bool { return $image->mime() === 'image/png'; } public function getCommand(): string { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString}" .' '.escapeshellarg($this->imagePath) .' --output='.escapeshellarg($this->imagePath); } } src/Optimizers/error_log 0000644 00000004727 15111676174 0011440 0 ustar 00 [26-Nov-2025 17:13:11 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Cwebp.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Cwebp.php on line 7 [26-Nov-2025 17:32:24 UTC] PHP Fatal error: Uncaught Error: Interface "Spatie\ImageOptimizer\Optimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/BaseOptimizer.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/BaseOptimizer.php on line 7 [26-Nov-2025 17:32:35 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Pngquant.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Pngquant.php on line 7 [26-Nov-2025 17:34:06 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Optipng.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Optipng.php on line 7 [26-Nov-2025 18:48:56 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Gifsicle.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Gifsicle.php on line 7 [26-Nov-2025 19:33:23 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Svgo.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Svgo.php on line 7 [26-Nov-2025 19:44:05 UTC] PHP Fatal error: Uncaught Error: Class "Spatie\ImageOptimizer\Optimizers\BaseOptimizer" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Jpegoptim.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/Optimizers/Jpegoptim.php on line 7 src/Optimizers/Cwebp.php 0000644 00000001056 15111676174 0011264 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Cwebp extends BaseOptimizer { public $binaryName = 'cwebp'; public function canHandle(Image $image): bool { return $image->mime() === 'image/webp'; } public function getCommand(): string { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString}" .' '.escapeshellarg($this->imagePath) .' -o '.escapeshellarg($this->imagePath); } } src/Optimizers/Svgo.php 0000644 00000001373 15111676174 0011144 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Svgo extends BaseOptimizer { public $binaryName = 'svgo'; public function canHandle(Image $image): bool { if ($image->extension() !== 'svg') { return false; } return in_array($image->mime(), [ 'text/html', 'image/svg', 'image/svg+xml', 'text/plain', ]); } public function getCommand(): string { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString}" .' --input='.escapeshellarg($this->imagePath) .' --output='.escapeshellarg($this->imagePath); } } src/Optimizers/Jpegoptim.php 0000644 00000000425 15111676174 0012161 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Jpegoptim extends BaseOptimizer { public $binaryName = 'jpegoptim'; public function canHandle(Image $image): bool { return $image->mime() === 'image/jpeg'; } } src/Optimizers/Gifsicle.php 0000644 00000001066 15111676174 0011752 0 ustar 00 <?php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; class Gifsicle extends BaseOptimizer { public $binaryName = 'gifsicle'; public function canHandle(Image $image): bool { return $image->mime() === 'image/gif'; } public function getCommand(): string { $optionString = implode(' ', $this->options); return "\"{$this->binaryPath}{$this->binaryName}\" {$optionString}" .' -i '.escapeshellarg($this->imagePath) .' -o '.escapeshellarg($this->imagePath); } } src/DummyLogger.php 0000644 00000001462 15111676174 0010313 0 ustar 00 <?php namespace Spatie\ImageOptimizer; use Psr\Log\LoggerInterface; class DummyLogger implements LoggerInterface { public function emergency($message, array $context = []): void { } public function alert($message, array $context = []): void { } public function critical($message, array $context = []): void { } public function error($message, array $context = []): void { } public function warning($message, array $context = []): void { } public function notice($message, array $context = []): void { } public function info($message, array $context = []): void { } public function debug($message, array $context = []): void { } public function log($level, $message, array $context = []): void { } } src/error_log 0000644 00000001725 15111676174 0007266 0 ustar 00 [19-Nov-2025 03:46:32 UTC] PHP Fatal error: Uncaught Error: Interface "Psr\Log\LoggerInterface" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php on line 7 [19-Nov-2025 10:26:44 UTC] PHP Fatal error: Uncaught Error: Interface "Psr\Log\LoggerInterface" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php on line 7 [26-Nov-2025 02:03:23 UTC] PHP Fatal error: Uncaught Error: Interface "Psr\Log\LoggerInterface" not found in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/spatie/image-optimizer/src/DummyLogger.php on line 7 src/OptimizerChainFactory.php 0000644 00000004016 15111676174 0012333 0 ustar 00 <?php namespace Spatie\ImageOptimizer; 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; 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); } return (new OptimizerChain()) ->addOptimizer(new Jpegoptim([ $jpegQuality, '--strip-all', '--all-progressive', ])) ->addOptimizer(new Pngquant([ $pngQuality, '--force', '--skip-if-larger', ])) ->addOptimizer(new Optipng([ '-i0', '-o2', '-quiet', ])) ->addOptimizer(new Svgo([ '--config=svgo.config.js', ])) ->addOptimizer(new Gifsicle([ '-b', '-O3', ])) ->addOptimizer(new Cwebp([ $webpQuality, '-m 6', '-pass 10', '-mt', ])) ->addOptimizer(new Avifenc([ $avifQuality, '-j all', '--min 0', '--max 63', '--minalpha 0', '--maxalpha 63', '-a end-usage=q', '-a tune=ssim', ])); } } src/Image.php 0000644 00000001314 15111676174 0007076 0 ustar 00 <?php namespace Spatie\ImageOptimizer; use InvalidArgumentException; class Image { protected $pathToImage = ''; public function __construct(string $pathToImage) { if (! file_exists($pathToImage)) { throw new InvalidArgumentException("`{$pathToImage}` does not exist"); } $this->pathToImage = $pathToImage; } public function mime(): string { return mime_content_type($this->pathToImage); } public function path(): string { return $this->pathToImage; } public function extension(): string { $extension = pathinfo($this->pathToImage, PATHINFO_EXTENSION); return strtolower($extension); } } README.md 0000644 00000033310 15111676174 0006034 0 ustar 00 # Easily optimize images using PHP [](https://packagist.org/packages/spatie/image-optimizer)  [](https://packagist.org/packages/spatie/image-optimizer) This package can optimize PNGs, JPGs, WEBPs, AVIFs, SVGs and GIFs by running them through a chain of various [image optimization tools](#optimization-tools). Here's how you can use it: ```php use Spatie\ImageOptimizer\OptimizerChainFactory; $optimizerChain = OptimizerChainFactory::create(); $optimizerChain->optimize($pathToImage); ``` The image at `$pathToImage` will be overwritten by an optimized version which should be smaller. The package will automatically detect which optimization binaries are installed on your system and use them. Here are some [example conversions](#example-conversions) that have been done by this package. Loving Laravel? Then head over to [the Laravel specific integration](https://github.com/spatie/laravel-image-optimizer). Using WordPress? Then try out [the WP CLI command](https://github.com/TypistTech/image-optimize-command). SilverStripe enthusiast? Don't waste time, go to [the SilverStripe module](https://github.com/axllent/silverstripe-image-optimiser). ## Support us [<img src="https://github-ads.s3.eu-central-1.amazonaws.com/image-optimizer.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/image-optimizer) We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). ## Installation You can install the package via composer: ```bash composer require spatie/image-optimizer ``` ### Optimization tools The package will use these optimizers if they are present on your system: - [JpegOptim](https://github.com/tjko/jpegoptim) - [Optipng](http://optipng.sourceforge.net/) - [Pngquant 2](https://pngquant.org/) - [SVGO 1](https://github.com/svg/svgo) - [Gifsicle](http://www.lcdf.org/gifsicle/) - [cwebp](https://developers.google.com/speed/webp/docs/precompiled) - [avifenc](https://github.com/AOMediaCodec/libavif/blob/main/doc/avifenc.1.md) Here's how to install all the optimizers on Ubuntu/Debian: ```bash sudo apt-get install jpegoptim sudo apt-get install optipng sudo apt-get install pngquant sudo npm install -g svgo sudo apt-get install gifsicle sudo apt-get install webp sudo apt-get install libavif-bin # minimum 0.9.3 ``` And here's how to install the binaries on MacOS (using [Homebrew](https://brew.sh/)): ```bash brew install jpegoptim brew install optipng brew install pngquant npm install -g svgo brew install gifsicle brew install webp brew install libavif ``` And here's how to install the binaries on Fedora/RHEL/CentOS: ```bash sudo dnf install epel-release sudo dnf install jpegoptim sudo dnf install optipng sudo dnf install pngquant sudo npm install -g svgo sudo dnf install gifsicle sudo dnf install libwebp-tools sudo dnf install libavif-tools ``` ## Which tools will do what? The package will automatically decide which tools to use on a particular image. ### JPGs JPGs will be made smaller by running them through [JpegOptim](http://freecode.com/projects/jpegoptim). These options are used: - `-m85`: this will store the image with 85% quality. This setting [seems to satisfy Google's Pagespeed compression rules](https://webmasters.stackexchange.com/questions/102094/google-pagespeed-how-to-satisfy-the-new-image-compression-rules) - `--strip-all`: this strips out all text information such as comments and EXIF data - `--all-progressive`: this will make sure the resulting image is a progressive one, meaning it can be downloaded using multiple passes of progressively higher details. ### PNGs PNGs will be made smaller by running them through two tools. The first one is [Pngquant 2](https://pngquant.org/), a lossy PNG compressor. We set no extra options, their defaults are used. After that we run the image through a second one: [Optipng](http://optipng.sourceforge.net/). These options are used: - `-i0`: this will result in a non-interlaced, progressive scanned image - `-o2`: this set the optimization level to two (multiple IDAT compression trials) ### SVGs SVGs will be minified by [SVGO](https://github.com/svg/svgo). SVGO's default configuration will be used, with the omission of the `cleanupIDs` and `removeViewBox` plugins because these are known to cause troubles when displaying multiple optimized SVGs on one page. Please be aware that SVGO can break your svg. You'll find more info on that in this [excellent blogpost](https://www.sarasoueidan.com/blog/svgo-tools/) by [Sara Soueidan](https://twitter.com/SaraSoueidan). ### GIFs GIFs will be optimized by [Gifsicle](http://www.lcdf.org/gifsicle/). These options will be used: - `-O3`: this sets the optimization level to Gifsicle's maximum, which produces the slowest but best results ### WEBPs WEBPs will be optimized by [Cwebp](https://developers.google.com/speed/webp/docs/cwebp). These options will be used: - `-m 6` for the slowest compression method in order to get the best compression. - `-pass 10` for maximizing the amount of analysis pass. - `-mt` multithreading for some speed improvements. - `-q 90` Quality factor that brings the least noticeable changes. (Settings are original taken from [here](https://medium.com/@vinhlh/how-i-apply-webp-for-optimizing-images-9b11068db349)) ### AVIFs AVIFs will be optimized by [avifenc](https://github.com/AOMediaCodec/libavif/blob/main/doc/avifenc.1.md). These options will be used: - `-a cq-level=23`: Constant Quality level. Lower values mean better quality and greater file size (0-63). - `-j all`: Number of jobs (worker threads, `all` uses all available cores). - `--min 0`: Min quantizer for color (0-63). - `--max 63`: Max quantizer for color (0-63). - `--minalpha 0`: Min quantizer for alpha (0-63). - `--maxalpha 63`: Max quantizer for alpha (0-63). - `-a end-usage=q` Rate control mode set to Constant Quality mode. - `-a tune=ssim`: SSIM as tune the encoder for distortion metric. (Settings are original taken from [here](https://web.dev/compress-images-avif/#create-an-avif-image-with-default-settings) and [here](https://github.com/feat-agency/avif)) ## Usage This is the default way to use the package: ``` php use Spatie\ImageOptimizer\OptimizerChainFactory; $optimizerChain = OptimizerChainFactory::create(); $optimizerChain->optimize($pathToImage); ``` The image at `$pathToImage` will be overwritten by an optimized version which should be smaller. The package will automatically detect which optimization binaries are installed on your system and use them. To keep the original image, you can pass through a second argument`optimize`: ```php use Spatie\ImageOptimizer\OptimizerChainFactory; $optimizerChain = OptimizerChainFactory::create(); $optimizerChain->optimize($pathToImage, $pathToOutput); ``` In that example the package won't touch `$pathToImage` and write an optimized version to `$pathToOutput`. ### Setting a timeout You can set the maximum of time in seconds that each individual optimizer in a chain can use by calling `setTimeout`: ```php $optimizerChain ->setTimeout(10) ->optimize($pathToImage); ``` In this example each optimizer in the chain will get a maximum 10 seconds to do it's job. ### Creating your own optimization chains If you want to customize the chain of optimizers you can do so by adding `Optimizer`s manually to an `OptimizerChain`. Here's an example where we only want `optipng` and `jpegoptim` to be used: ```php use Spatie\ImageOptimizer\OptimizerChain; use Spatie\ImageOptimizer\Optimizers\Jpegoptim; use Spatie\ImageOptimizer\Optimizers\Pngquant; $optimizerChain = (new OptimizerChain) ->addOptimizer(new Jpegoptim([ '--strip-all', '--all-progressive', ])) ->addOptimizer(new Pngquant([ '--force', ])) ``` Notice that you can pass the options an `Optimizer` should use to its constructor. ### Writing a custom optimizers Want to use another command line utility to optimize your images? No problem. Just write your own optimizer. An optimizer is any class that implements the `Spatie\ImageOptimizer\Optimizers\Optimizer` interface: ```php namespace Spatie\ImageOptimizer\Optimizers; use Spatie\ImageOptimizer\Image; interface Optimizer { /** * Returns the name of the binary to be executed. * * @return string */ public function binaryName(): string; /** * Determines if the given image can be handled by the optimizer. * * @param \Spatie\ImageOptimizer\Image $image * * @return bool */ public function canHandle(Image $image): bool; /** * Set the path to the image that should be optimized. * * @param string $imagePath * * @return $this */ public function setImagePath(string $imagePath); /** * Set the options the optimizer should use. * * @param array $options * * @return $this */ public function setOptions(array $options = []); /** * Get the command that should be executed. * * @return string */ public function getCommand(): string; } ``` If you want to view an example implementation take a look at [the existing optimizers](https://github.com/spatie/image-optimizer/tree/master/src/Optimizers) shipped with this package. You can easily add your optimizer by using the `addOptimizer` method on an `OptimizerChain`. ``` php use Spatie\ImageOptimizer\ImageOptimizerFactory; $optimizerChain = OptimizerChainFactory::create(); $optimizerChain ->addOptimizer(new YourCustomOptimizer()) ->optimize($pathToImage); ``` ## Logging the optimization process By default the package will not throw any errors and just operate silently. To verify what the package is doing you can set a logger: ```php use Spatie\ImageOptimizer\OptimizerChainFactory; $optimizerChain = OptimizerChainFactory::create(); $optimizerChain ->useLogger(new MyLogger()) ->optimize($pathToImage); ``` A logger is a class that implements `Psr\Log\LoggerInterface`. A good logging library that's fully compliant is [Monolog](https://github.com/Seldaek/monolog). The package will write to log which `Optimizers` are used, which commands are executed and their output. ## Example conversions Here are some real life example conversions done by this package. Methodology for JPG, WEBP, AVIF images: the [original image](https://unsplash.com/photos/jTeQavJjBDs) has been fed to [spatie/image](https://github.com/spatie/image) (using the default GD driver) and resized to 2048px width: ```php Spatie\Image\Image::load('original.jpg') ->width(2048) ->save('image.jpg'); // image.png, image.webp, image.avif ``` ### jpg  Original<br> 771 KB  Optimized<br> 511 KB (-33.7%, DSSIM: 0.00052061) credits: Jeff Sheldon, via [Unsplash](https://unsplash.com) ### webp  Original<br> 461 KB  Optimized<br> 184 KB (-60.0%, DSSIM: 0.00166036) credits: Jeff Sheldon, via [Unsplash](https://unsplash.com) ### avif  Original<br> 725 KB  Optimized<br> 194 KB (-73.2%, DSSIM: 0.00163751) credits: Jeff Sheldon, via [Unsplash](https://unsplash.com) ### png Original: Photoshop 'Save for web' | PNG-24 with transparency<br> 39 KB  Optimized<br> 16 KB (-59%, DSSIM: 0.00000251)  ### svg Original: Illustrator | Web optimized SVG export<br> 25 KB  Optimized<br> 20 KB (-21.5%)  ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. ## Testing ``` bash composer test ``` ## Contributing Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details. ## Security If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker. ## Postcardware You're free to use this package (it's [MIT-licensed](.github/LICENSE.md)), but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium. We publish all received postcards [on our company website](https://spatie.be/en/opensource/postcards). ## Credits - [Freek Van der Herten](https://github.com/freekmurze) - [All Contributors](../../contributors) This package has been inspired by [psliwa/image-optimizer](https://github.com/psliwa/image-optimizer) Emotional support provided by [Joke Forment](https://twitter.com/pronneur) ## License The MIT License (MIT). Please see [License File](.github/LICENSE.md) for more information. LICENSE 0000644 00000002042 15111676175 0005561 0 ustar 00 MIT License Copyright (c) Spatie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. composer.json 0000644 00000002340 15111676175 0007277 0 ustar 00 { "name": "spatie/image-optimizer", "description": "Easily optimize images using PHP", "keywords": [ "spatie", "image-optimizer" ], "homepage": "https://github.com/spatie/image-optimizer", "license": "MIT", "authors": [ { "name": "Freek Van der Herten", "email": "freek@spatie.be", "homepage": "https://spatie.be", "role": "Developer" } ], "require": { "php": "^7.3|^8.0", "ext-fileinfo": "*", "psr/log": "^1.0 | ^2.0 | ^3.0", "symfony/process": "^4.2|^5.0|^6.0|^7.0" }, "require-dev": { "pestphp/pest": "^1.21", "phpunit/phpunit": "^8.5.21|^9.4.4", "symfony/var-dumper": "^4.2|^5.0|^6.0|^7.0" }, "autoload": { "psr-4": { "Spatie\\ImageOptimizer\\": "src" } }, "autoload-dev": { "psr-4": { "Spatie\\ImageOptimizer\\Test\\": "tests" }, "files": [ "tests/helpers.php" ] }, "scripts": { "test": "vendor/bin/phpunit" }, "config": { "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true } } } svgo.config.js 0000644 00000000310 15111676175 0007330 0 ustar 00 module.exports = { plugins: [ { name: 'preset-default', params: { overrides: { cleanupIDs: false, removeViewBox: false, }, }, }, ], }; CHANGELOG.md 0000644 00000011266 15111676175 0006375 0 ustar 00 # Changelog All notable changes to `image-optimizer` will be documented in this file ## 1.7.1 - 2023-07-27 ### What's Changed - libavif version note by @0xb4lint in https://github.com/spatie/image-optimizer/pull/199 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.7.0...1.7.1 ## 1.7.0 - 2023-07-22 ### What's Changed - README.md file size fixes, DSSIM score, optimized webp replaced by @0xb4lint in https://github.com/spatie/image-optimizer/pull/197 - added AVIF support by @0xb4lint in https://github.com/spatie/image-optimizer/pull/198 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.6.4...1.7.0 ## 1.6.4 - 2023-03-10 ### What's Changed - SVGO 3 Support by @l-alexandrov in https://github.com/spatie/image-optimizer/pull/186 ### New Contributors - @l-alexandrov made their first contribution in https://github.com/spatie/image-optimizer/pull/186 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.6.3...1.6.4 ## 1.6.3 - 2023-02-28 ### What's Changed - Update .gitattributes by @PaolaRuby in https://github.com/spatie/image-optimizer/pull/161 - Feature: Convert PHPUnit tests to Pest by @mansoorkhan96 in https://github.com/spatie/image-optimizer/pull/167 - Add dependabot automation by @patinthehat in https://github.com/spatie/image-optimizer/pull/173 - Allow Pest Composer Plugin (fix failing tests) by @patinthehat in https://github.com/spatie/image-optimizer/pull/176 - Update Dependabot Automation by @patinthehat in https://github.com/spatie/image-optimizer/pull/175 - DOC: adding SilverStripe link by @sunnysideup in https://github.com/spatie/image-optimizer/pull/177 - Bump dependabot/fetch-metadata from 1.3.5 to 1.3.6 by @dependabot in https://github.com/spatie/image-optimizer/pull/183 - WebP Quality Option by @jan-tricks in https://github.com/spatie/image-optimizer/pull/185 - Bump actions/checkout from 2 to 3 by @dependabot in https://github.com/spatie/image-optimizer/pull/174 ### New Contributors - @PaolaRuby made their first contribution in https://github.com/spatie/image-optimizer/pull/161 - @mansoorkhan96 made their first contribution in https://github.com/spatie/image-optimizer/pull/167 - @patinthehat made their first contribution in https://github.com/spatie/image-optimizer/pull/173 - @sunnysideup made their first contribution in https://github.com/spatie/image-optimizer/pull/177 - @dependabot made their first contribution in https://github.com/spatie/image-optimizer/pull/183 - @jan-tricks made their first contribution in https://github.com/spatie/image-optimizer/pull/185 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.6.2...1.6.3 ## 1.6.2 - 2021-12-21 ## What's Changed - add support for Symfony 6 by @Nielsvanpach in https://github.com/spatie/image-optimizer/pull/155 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.6.1...1.6.2 ## 1.6.1 - 2021-11-17 ## What's Changed - Add PHP 8.1 support by @freekmurze in https://github.com/spatie/image-optimizer/pull/154 **Full Changelog**: https://github.com/spatie/image-optimizer/compare/1.5.0...1.6.1 ## 1.5.0 - 2021-10-18 - Support new releases of psr/log (#150) ## 1.4.0 - 2021-04-22 - use `--skip-if-larger` pngquant option by default (#140) ## 1.3.2 - 2020-11-28 - improve gifsicle (#131) ## 1.3.1 - 2020-10-20 - fix empty string setBinaryPath() (#129) ## 1.3.0 - 2020-10-10 - add support for php 8.0 ## 1.2.1 - 2019-11-23 - allow symfony 5 components ## 1.2.0 - 2019-08-28 - add support for webp ## 1.1.6 - 2019-08-26 - do not export docs directory ## 1.1.5 - 2019-01-15 - fix for svg's - make compatible with PHPUnit 8 ## 1.1.4 - 2019-01-14 - fix deprecation warning for passing strings to processes ## 1.1.3 - 2018-11-19 - require the fileinfo extension ## 1.1.2 - 2018-10-10 - make sure all optimizers use `binaryPath` ## 1.1.1 - 2018-09-10 - fix logger output ## 1.1.0 - 2018-06-05 - add `setBinaryPath` ## 1.0.14 - 2018-03-07 - support more symfony versions ## 1.0.13 - 2018-02-26 - added `text/plain` to the list of valid svg mime types ## 1.0.12. - 2018-02-21 - added `image/svg+xml` mime type ## 1.0.11 - 2018-02-08 - SVG mime type detection in PHP 7.2 ## 1.0.10 - 2018-02-08 - Support symfony ^4.0 - Support phpunit ^7.0 ## 1.0.9 - 2017-11-03 - fix shell command quotes ## 1.0.8 - 2017-09-14 - allow Symfony 2 components - make Google Pagespeed tests pass ## 1.0.7 - 2017-07-29 - lower requirements of dependencies ## 1.0.6 - 2017-07-10 - fix `jpegoptim` parameters ## 1.0.4 - 2017-07-07 - make `setTimeout` chainable ## 1.0.3 - 2017-07-06 - fix `composer.json` ## 1.0.2 - 2017-07-06 - fix for Laravel 5.5 users ## 1.0.1 - 2017-07-06 - improve security ## 1.0.0 - 2017-07-05 - initial release
Simpan