php-svg-optimizer is a lightweight PHP library designed to optimize SVG files by applying various transformations and
cleanup operations. The library ensures that the optimized SVG files are compliant with SVG 2.0 specifications.
The tool strives to optimize as much as possible without losing any data that could distort the image's quality, ensuring the resulting SVG remains visually identical to the original while being more efficient in terms of size and performance.
| Version | PHP | Documentation |
|---|---|---|
| ^7.2 | ^8.3 | current |
ext-dom: Required PHP extension for XML handling.ext-libxml: Required PHP extension for XML error handling.ext-mbstring: Required PHP extension for multibyte string handling.
To install the library, run:
composer require mathiasreker/php-svg-optimizerYou can use this library either as a command-line tool (CLI) or as a standalone package.
vendor/bin/svg-optimizer [options] process <path1> <path2> ...Options:
-h , --help Display help for the command.
-c , --config Path to a JSON file with custom optimization rules. If not provided, all default optimizations will be applied.
-d , --dry-run Only calculate potential savings without modifying the files.
-q , --quiet Suppress all output except errors.
-v , --version Display the version of the library.
Commands:
Process Provide a list of directories or files to process.vendor/bin/svg-optimizer --dry-run process /path/to/svgs
vendor/bin/svg-optimizer --config=config.json process /path/to/file.svg
vendor/bin/svg-optimizer --config='{"removeUnsafeElements": true}' process /path/to/file.svg
vendor/bin/svg-optimizer --quiet process /path/to/file.svg{
"convertColorsToHex": true,
"convertCssClassesToAttributes": true,
"convertEmptyTagsToSelfClosing": true,
"convertInlineStylesToAttributes": true,
"flattenGroups": false,
"minifySvgCoordinates": true,
"minifyTransformations": true,
"removeComments": true,
"removeDefaultAttributes": true,
"removeDeprecatedAttributes": true,
"removeDoctype": true,
"removeEmptyAttributes": true,
"removeEnableBackgroundAttribute": true,
"removeInkscapeFootprints": true,
"removeInvisibleCharacters": true,
"removeMetadata": true,
"removeTitleAndDesc": true,
"removeUnnecessaryWhitespace": true,
"removeUnsafeElements": false,
"removeUnusedMasks": true,
"removeUnusedNamespaces": true,
"removeWidthHeightAttributes": false,
"sortAttributes": true
}To ensure robustness when using the library, it's crucial to handle exceptions, as invalid or malformed SVG files could lead to runtime errors. Catching these exceptions will allow you to manage potential issues gracefully and prevent your application from crashing.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade;
try {
$svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg')
->withRules(
convertColorsToHex: true,
convertCssClassesToAttributes: true,
convertEmptyTagsToSelfClosing: true,
convertInlineStylesToAttributes: true,
flattenGroups: false,
minifySvgCoordinates: true,
minifyTransformations: true,
removeComments: true,
removeDefaultAttributes: true,
removeDeprecatedAttributes: true,
removeDoctype: true,
removeEmptyAttributes: true,
removeEnableBackgroundAttribute: true,
removeInkscapeFootprints: true,
removeInvisibleCharacters: true,
removeMetadata: true,
removeTitleAndDesc: true,
removeUnnecessaryWhitespace: true,
removeUnsafeElements: false,
removeUnusedMasks: true,
removeUnusedNamespaces: true,
removeWidthHeightAttributes: false,
sortAttributes: true,
)
->optimize()
->saveToFile('path/to/output.svg');
} catch (\Exception $exception) {
echo $exception->getMessage();
}<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade;
try {
$svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg')
->optimize()
->saveToFile('path/to/output.svg');
$metaData = $svgOptimizer->getMetaData();
echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL);
echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL);
echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL);
echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL);
} catch (\Exception $exception) {
echo $exception->getMessage();
}<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade;
try {
$svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg')
->optimize();
echo sprintf('Get content: ', $svgOptimizer->getContent(), \PHP_EOL);
$metaData = $svgOptimizer->getMetaData();
echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL);
echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL);
echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL);
echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL);
} catch (\Exception $exception) {
echo $exception->getMessage();
}<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use MathiasReker\PhpSvgOptimizer\Service\Facade\SvgOptimizerFacade;
try {
$svgOptimizer = SvgOptimizerFacade::fromString('<svg>...</svg>')
->optimize();
echo sprintf('Content: ', $svgOptimizer->getContent(), \PHP_EOL);
$metaData = $svgOptimizer->getMetaData();
echo sprintf('Optimized size: %d bytes%s', $metaData->getOptimizedSize(), \PHP_EOL);
echo sprintf('Original size: %d bytes%s', $metaData->getOriginalSize(), \PHP_EOL);
echo sprintf('Size reduction: %d bytes%s', $metaData->getSavedBytes(), \PHP_EOL);
echo sprintf('Reduction percentage: %s %%%s', $metaData->getSavedPercentage(), \PHP_EOL);
} catch (\Exception $exception) {
echo $exception->getMessage();
}Static factory method to create SvgOptimizerFacade from a file path.
$svgOptimizer = SvgOptimizerFacade::fromFile('path/to/source.svg');Static factory method to create SvgOptimizerFacade from a string.
$svgOptimizer = SvgOptimizerFacade::fromString('<svg>...</svg>');Configure which SVG optimization rules to apply. The method accepts boolean parameters that determine whether specific rules should be enabled or disabled.
Converts rgb() color values to hexadecimal format:
$svgOptimizer->withRules(convertColorsToHex: true);Converts css classes to attributes:
$svgOptimizer->withRules(convertCssClassesToAttributes: true);Converts empty tags to self-closing tags:
$svgOptimizer->withRules(convertEmptyTagsToSelfClosing: true);Converts inline styles to attributes:
$svgOptimizer->withRules(convertInlineStylesToAttributes: true);Flattens nested <g> elements, moving their child elements up to the parent node:
$svgOptimizer->withRules(flattenGroups: true);Minifies coordinate values by removing unnecessary precision:
$svgOptimizer->withRules(minifySvgCoordinates: true);Minifies transformation attributes by removing redundant values:
$svgOptimizer->withRules(minifyTransformations: true);Removes all comments from the SVG:
$svgOptimizer->withRules(removeComments: true);Removes default attribute values that match common defaults:
$svgOptimizer->withRules(removeDefaultAttributes: true);Removes deprecated attributes from the SVG:
$svgOptimizer->withRules(removeDeprecatedAttributes: true);Removes the SVG doctype declaration:
$svgOptimizer->withRules(removeDoctype: true);Removes empty attributes from the SVG:
$svgOptimizer->withRules(removeEmptyAttributes: true);Removes the enable-background attribute from the SVG:
$svgOptimizer->withRules(removeEnableBackgroundAttribute: true);Removes Inkspace-specific footprints from the SVG:
$svgOptimizer->withRules(removeInkscapeFootprints: true);Removes invisible characters from the SVG:
$svgOptimizer->withRules(removeInvisibleCharacters: true);Removes <metadata> tags from the SVG:
$svgOptimizer->withRules(removeMetadata: true);Removes <title> and <desc> tags from the SVG:
$svgOptimizer->withRules(removeTitleAndDesc: true);Cleans up unnecessary whitespace in the SVG:
$svgOptimizer->withRules(removeUnnecessaryWhitespace: true);Removes unused namespaces from the SVG:
$svgOptimizer->withRules(removeUnusedNamespaces: true);Removes the width and height attributes from the <svg> element, allowing the SVG to scale automatically based on its
viewBox (risky):
$svgOptimizer->withRules(removeWidthHeightAttributes: false);Removes unsafe elements from the SVG (risky):
$svgOptimizer->withRules(removeUnsafeElements: true);Removes <mask> elements that are not referenced or used anywhere in the SVG:
$svgOptimizer->withRules(removeUnusedMasks: true);Sorts attributes within each element:
$svgOptimizer->withRules(sortAttributes: true);Below you see the default configuration. You can configure each rule individually by passing the desired values to it:
$svgOptimizer->withRules(
convertColorsToHex: true,
convertCssClassesToAttributes: true,
convertEmptyTagsToSelfClosing: true,
convertInlineStylesToAttributes: true,
flattenGroups: false,
minifySvgCoordinates: true,
minifyTransformations: true,
removeComments: true,
removeDefaultAttributes: true,
removeDeprecatedAttributes: true,
removeDoctype: true,
removeEmptyAttributes: true,
removeEnableBackgroundAttribute: true,
removeInkscapeFootprints: true,
removeInvisibleCharacters: true,
removeMetadata: true,
removeTitleAndDesc: true,
removeUnnecessaryWhitespace: true,
removeUnsafeElements: false,
removeUnusedMasks: true,
removeUnusedNamespaces: true,
removeWidthHeightAttributes: false,
sortAttributes: true,
);Finalizes the optimization process and generates the optimized SVG file.
$svgOptimizer->optimize();Saves the optimized SVG file to the specified path.
$svgOptimizer->saveToFile('path/to/output.svg');Returns the optimized SVG content.
$svgOptimizer->getContent();Returns the size of the optimized SVG file.
$svgOptimizer->getMetaData()->getOptimizedSize();Returns the size of the original SVG file.
$svgOptimizer->getMetaData()->getOriginalSize();Returns the number of bytes saved by the optimization process.
$svgOptimizer->getMetaData()->getSavedBytes();Returns the percentage of bytes saved by the optimization process.
$svgOptimizer->getMetaData()->getSavedPercentage();For a complete list of proposed features and known issues, see the open issues.
We welcome all contributions! If you have ideas for improvements, feel free to fork the repository and submit a pull request. You can also open an issue. If you find this project helpful, don’t forget to give it a star!
The library implements the Strategy Pattern, where strategies are encapsulated as "rules" located in the
/src/Service/Rule directory.
Create a new final readonly class in the /src/Service/Rule directory and implement
the SvgOptimizerRuleInterface. This
interface will define the logic for your rule.
Write comprehensive unit tests for your rule in the /tests/Unit/Service/Rule directory. Ensure the tests cover
various scenarios to verify the correct behavior and edge cases for your rule.
- Register the rule in the SVG optimizer builder located at
/src/Service/Facade/SvgOptimizerFacade.php. - Add your rule to the rule enum in
/src/Type/Rule.php. - Include the rule in the processor by updating
/src/Processor/SvgFileProcessor.php.
Document the functionality and purpose of your rule in the README.md to ensure users understand its behavior and
usage.
To use the project with Docker, you can start the container using:
docker-compose up -dThen, access the container:
docker exec -it php-svg-optimizer bashRun static analysis:
composer analyze:allRun tests:
composer testFix code style:
composer lint:allBuild badges:
composer build:badgesThis project is licensed under the MIT License. See the LICENSE file for more information.
Although the tool has been thoroughly tested and is built in a way that avoids risky changes, its use is at your own risk. We cannot guarantee that it will be fully compatible with all SVG files or workflows. It is highly recommended to test the tool with sample SVG files and ensure compatibility with your specific use case before using it in a production environment.
