Optimize images in your Laravel app

Overview

Optimize images in your Laravel app

Latest Version on Packagist Tests Total Downloads

This package is the Laravel 6.0 and up specific integration of spatie/image-optimizer. It can optimize PNGs, JPGs, SVGs and GIFs by running them through a chain of various image optimization tools. The package will automatically detect which optimization binaries are installed on your system and use them.

Here's how you can use it:

use ImageOptimizer;

// the image will be replaced with an optimized version which should be smaller
ImageOptimizer::optimize($pathToImage);

// if you use a second parameter the package will not modify the original
ImageOptimizer::optimize($pathToImage, $pathToOptimizedImage);

You don't like facades you say? No problem! Just resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:

app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);

The package also contains a middleware to automatically optimize all images in an request.

Don't use Laravel you say? No problem! Just use the underlying spatie/image-optimizer directly.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

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. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/laravel-image-optimizer

The package will automatically register itself.

The package uses a bunch of binaries to optimize images. To learn which ones on how to install them, head over to the optimization tools section in the readme of the underlying image-optimizer package. That readme also contains info on what these tools will do to your images.

The package comes with some sane defaults to optimize images. You can modify that configuration by publishing the config file.

php artisan vendor:publish --provider="Spatie\LaravelImageOptimizer\ImageOptimizerServiceProvider"

This is the contents of the config/image-optimizer file that will be published:

use Spatie\ImageOptimizer\Optimizers\Svgo;
use Spatie\ImageOptimizer\Optimizers\Optipng;
use Spatie\ImageOptimizer\Optimizers\Gifsicle;
use Spatie\ImageOptimizer\Optimizers\Pngquant;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;
use Spatie\ImageOptimizer\Optimizers\Cwebp;

return [
    /**
     * When calling `optimize` the package will automatically determine which optimizers
     * should run for the given image.
     */
    'optimizers' => [

        Jpegoptim::class => [
            '-m85', // set maximum quality to 85%
            '--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
        ],

        Pngquant::class => [
            '--force' // required parameter for this package
        ],

        Optipng::class => [
            '-i0', // this will result in a non-interlaced, progressive scanned image
            '-o2',  // this set the optimization level to two (multiple IDAT compression trials)
            '-quiet' // required parameter for this package
        ],

        Svgo::class => [
            '--disable=cleanupIDs' // disabling because it is know to cause troubles
        ],

        Gifsicle::class => [
            '-b', // required parameter for this package
            '-O3' // this produces the slowest but best results
        ],
        
        Cwebp::class => [
            '-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.
        ],
    ],

    /**
     * The maximum time in seconds each optimizer is allowed to run separately.
     */
    'timeout' => 60,

    /**
     * If set to `true` all output of the optimizer binaries will be appended to the default log.
     * You can also set this to a class that implements `Psr\Log\LoggerInterface`.
     */
    'log_optimizer_activity' => false,
];

If you want to automatically optimize images that get uploaded to your application add the \Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages::class in the http kernel.

// app/Http/Kernel.php
protected $routeMiddleware = [
   ...
   'optimizeImages' => \Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages::class,
];

Usage

You can resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:

// the image will be replaced with an optimized version which should be smaller
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);

// if you use a second parameter the package will not modify the original
app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage, $pathToOptimizedImage);

Using the facade

use ImageOptimizer;

// the image will be replaced with an optimized version which should be smaller
ImageOptimizer::optimize($pathToImage);

// if you use a second parameter the package will not modify the original
ImageOptimizer::optimize($pathToImage, $pathToOptimizedImage);

You don't like facades you say? No problem! Just resolve a configured instance of Spatie\ImageOptimizer\OptimizerChain out of the container:

app(Spatie\ImageOptimizer\OptimizerChain::class)->optimize($pathToImage);

Using the middleware

All images that in requests to routes that use the optimizeImages-middleware will be optimized automatically.

Route::middleware('optimizeImages')->group(function () {
    // all images will be optimized automatically
    Route::post('upload-images', 'UploadController@index');
});

Adding your own optimizers

To learn how to create your own optimizer read the "Writing custom optimizers" section in the readme of the underlying spatie/image-optimizer package.

You can add the fully qualified classname of your optimizer as a key in the optimizers array in the config file.

Example conversions

Here are some example conversions that were made by the optimizer.

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package (it's MIT-licensed), 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.

Credits

The idea of a middleware that optimizes all files in a request is taken from approached/laravel-image-optimizer.

License

The MIT License (MIT). Please see License File for more information.

Comments
  • chore: update readme minimum laravel version

    chore: update readme minimum laravel version

    As per https://github.com/spatie/laravel-image-optimizer/issues/65 the supported version in the readme is incorrect.

    I have updated it as per the current composer.json :smile:

    opened by atymic 4
  • Bugfix for custom logger

    Bugfix for custom logger

    Customer logger using laravel config [setting log_optimizer_activity' => MyCustomLogger ] throws an exception (Logger is not a suitable logger). Reason being a wrong type check.

    opened by tmp-hallenser 3
  • Optimize just valid (uploaded without errors) files

    Optimize just valid (uploaded without errors) files

    When an image wasn't uploaded successfully (usually due to upload_max_filesize, post_max_size or other configuration) middleware attempt to optimize a path of an unexisting image then throw an InvalidArgumentException with unhelpful message '' does not exist preventing other middleware to handle the request such a ValidatePostSize, and even FormRequest validation. the solution is simple since the $file being handled is an instance of Symfony UploadedFile we can use isValid() method.

    This PR fix #67

    opened by yaayes 3
  • Add Dependabot Automation

    Add Dependabot Automation

    Overview

    This PR adds dependabot automation for this repository.

    Description

    This PR adds a dependabot configuration file that enables weekly update checks for all github actions used within workflows in the project.

    This PR includes a workflow that automatically merges dependabot PRs for minor and patch version updates (major version bumps must be manually merged to avoid breaking changes, with one exception - see below).

    When performing auto-merging of PRs, Github Actions that have a major version update AND a compatibility score of >=90% are automatically merged as way to reduce the manual work of merging PRs that are of no risk of breaking changes. ONLY Github Actions that have a major version update are considered for automatic merging. Other dependencies are excluded.

    Using these features will help keep all workflows up to date with a minimal amount of manual intervention necessary.

    Notes

    This functionality has already been added to the Spatie laravel package skeleton repository.

    id:dependabot-automation/v2

    opened by patinthehat 1
  • Automatically wrap optimize call in Storage::disk()->path()

    Automatically wrap optimize call in Storage::disk()->path()

    Resolves #95

    If the given $pathToImage for the call to optimize does not exist, this PR will try using Storage::disk($disk)->path($pathToImage).

    In case the user wants to use a different disk, this PR also extended the API and added a disk method on the facade.

    This way you can have code like this in a controller without needing to manually wrap the $pathToImage returned by the storeAs method in laravel.

    use ImageOptimizer;
    use Illuminate\Http\Request;
    //...
    function store(Request $request)
    {
      $file = $request->file('image');
    
      $filename = $file->getClientOriginalName();
      $pathToImage = $file->storeAs('public/images/', $filename);
      ImageOptimizer::optimize($pathToImage);
    }
    
    opened by ahallhognason 1
  • Move orchestra testbench to dev dependencies

    Move orchestra testbench to dev dependencies

    I noticed this while rolling out a release for our Laravel app recently updated to version 7. The server PHP version is 7.2.28 and this prevented us to deploy the changes

    opened by Lloople 1
  • Add missing config option so that jpegs actually get properly optimized

    Add missing config option so that jpegs actually get properly optimized

    The OptimizerChainFactory in spatie/image-optimizer has the -m85 option for JpegOptim, whereas the config for the Laravel package is missing it. Therefore when using this package, jpegs are barely being optimized. This pull adds the missing option into the config, restoring parity between the two packages.

    opened by ockle 1
  • Fix issue with middleware and images in multidimensional input arrays

    Fix issue with middleware and images in multidimensional input arrays

    If, for example, an image is uploaded via an input such as:

    <input type="file" name="images[foo][bar]">
    

    then the middleware will throw an error such as that seen in #19 and #25. #26 was intended to fix this, but for some reason the author of that pull limited the flatten to 1 depth. This pull removes that limit so that all files at any depth can be processed.

    opened by ockle 1
  • Bump actions/checkout from 2 to 3

    Bump actions/checkout from 2 to 3

    Bumps actions/checkout from 2 to 3.

    Release notes

    Sourced from actions/checkout's releases.

    v3.0.0

    • Updated to the node16 runtime by default
      • This requires a minimum Actions Runner version of v2.285.0 to run, which is by default available in GHES 3.4 or later.

    v2.5.0

    What's Changed

    Full Changelog: https://github.com/actions/checkout/compare/v2...v2.5.0

    v2.4.2

    What's Changed

    Full Changelog: https://github.com/actions/checkout/compare/v2...v2.4.2

    v2.4.1

    • Fixed an issue where checkout failed to run in container jobs due to the new git setting safe.directory

    v2.4.0

    • Convert SSH URLs like org-<ORG_ID>@github.com: to https://github.com/ - pr

    v2.3.5

    Update dependencies

    v2.3.4

    v2.3.3

    v2.3.2

    Add Third Party License Information to Dist Files

    v2.3.1

    Fix default branch resolution for .wiki and when using SSH

    v2.3.0

    Fallback to the default branch

    v2.2.0

    Fetch all history for all tags and branches when fetch-depth=0

    v2.1.1

    Changes to support GHES (here and here)

    ... (truncated)

    Changelog

    Sourced from actions/checkout's changelog.

    Changelog

    v3.1.0

    v3.0.2

    v3.0.1

    v3.0.0

    v2.3.1

    v2.3.0

    v2.2.0

    v2.1.1

    • Changes to support GHES (here and here)

    v2.1.0

    v2.0.0

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump actions/setup-node from 1 to 3

    Bump actions/setup-node from 1 to 3

    Bumps actions/setup-node from 1 to 3.

    Release notes

    Sourced from actions/setup-node's releases.

    Add support for asdf format and update actions/cache version to 3.0.0

    In scope of this release we updated actions/cache package as the new version contains fixes for caching error handling. Moreover, we added support for asdf format as Node.js version file actions/setup-node#373. Besides, we introduced new output node-version and added npm-shrinkwrap.json to dependency file patterns: actions/setup-node#439

    Update actions/cache version to 2.0.2

    In scope of this release we updated actions/cache package as the new version contains fixes related to GHES 3.5 (actions/setup-node#460)

    v3.0.0

    In scope of this release we changed version of the runtime Node.js for the setup-node action and updated package-lock.json file to v2.

    Breaking Changes

    Fix logic of error handling for npm warning and uncaught exception

    In scope of this release we fix logic of error handling related to caching (actions/setup-node#358) and (actions/setup-node#359).

    In the previous behaviour we relied on stderr output to throw error. The warning messages from package managers can be written to the stderr's output. For now the action will throw an error only if exit code differs from zero. Besides, we add logic to сatch and log unhandled exceptions.

    Adding Node.js version file support

    In scope of this release we add the node-version-file input and update actions/cache dependency to the latest version.

    Adding Node.js version file support

    The new input (node-version-file) provides functionality to specify the path to the file containing Node.js's version with such behaviour:

    • If the file does not exist the action will throw an error.
    • If you specify both node-version and node-version-file inputs, the action will use value from the node-version input and throw the following warning: Both node-version and node-version-file inputs are specified, only node-version will be used.
    • For now the action does not support all of the variety of values for Node.js version files. The action can handle values according to the documentation and values with v prefix (v14)
    steps:
      - uses: actions/checkout@v2
      - name: Setup node from node version file
        uses: actions/setup-node@v2
        with:
          node-version-file: '.nvmrc'
      - run: npm install
      - run: npm test
    

    Update actions/cache dependency to 1.0.8 version.

    We updated actions/cache dependency to the latest version (1.0.8). For more information please refer to the toolkit/cache.

    Add "cache-hit" output

    This release introduces a new output: cache-hit (#327).

    The cache-hit output contains boolean value indicating that an exact match was found for the key. It shows that the action uses already existing cache or not. The output is available only if cache is enabled.

    Support caching for mono repos and repositories with complex structure

    This release introduces dependency caching support for mono repos and repositories with complex structure (#305).

    By default, the action searches for the dependency file (package-lock.json or yarn.lock) in the repository root. Use the cache-dependency-path input for cases when multiple dependency files are used, or they are located in different subdirectories. This input supports wildcards or a list of file names for caching multiple dependencies.

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
Releases(1.7.0)
Owner
Spatie
We create open source, digital products and courses for the developer community
Spatie
A web app for the resolution of a mobile game in wich you have 4 images and a list of letters, then a few boxes to fill with the word connecting the four images.

4images_1mot_solutions A web app for the resolution of a mobile game in wich you have 4 images and a list of letters, then a few boxes to fill with th

FOTSO Claude 3 Jan 13, 2022
Optimize your application by warming up OpCode.

OpCode Warmer (composer plugin) Optimize your application by warming up OpCode. Requirements PHP >=7.0 Zend extension Opcache extension Sockets compos

Jérémy Derussé 177 Oct 6, 2022
A hacky PHP script to download posts, images, videos and framework grading from Parent Zone

ParentZoneDownloader A hacky PHP script to download posts, images, videos and framework grading from Parent Zone Pre-Requisites Tested on PHP 7.4, but

null 2 Sep 6, 2021
Allow SVG images to be used in Magento CMS blocks and pages via the TinyMCE Wysiwyg Editor.

Hyvä Themes - SVG support for the Magento CMS Wysiwyg Editor Allow SVG images to be used in CMS blocks and pages via the TinyMCE Wysiwyg Editor. hyva-

Hyvä 14 Dec 15, 2022
Docker images for Cyber_Security hakathon 2021.

This repository contains a set of vulnerable Docker images for attacking the container environment compiled for Cyber_Security hackathon 2021. Require

null 1 Dec 1, 2022
A FREE Wordpress Plugin to compress and convert images using cwebp, jpegoptim and optipng.

Squidge Is FREE WordpPress Plugin built for developers in mind compressing and convert images using jpegoptim, optipng, cwebp, and libavif. It's extre

Ainsley Clark 23 Dec 10, 2022
An open source tool that lets you create a SaaS website from docker images in 10 minutes.

简体中文 Screenshots for members ( who subscribe the plan ) for admin ⚠️ This document was translated into English by deepl and can be improved by PR An o

Easy 669 Jan 5, 2023
Super simple share buttons for WordPress. No images, no css, no javascript

Developer Share Buttons A super lightweight social sharing solution using either the Web Share API or simple sharing links. Description A simple, cust

Grant Richmond 28 Nov 13, 2022
Smd imagery - A Textpattern CMS plugin for managing images in the Write panel.

smd_imagery Insert images into your Write panel. Very handy for people who run photoblog or image-heavy sites, or those who categorise images for incl

Stef Dawson 5 Nov 15, 2022
Oui instagram - Instagram user infos and recent images embedding plugin for @textpattern

oui_instagram Easily display Instagram recent images galleries. Plugin requirements required: Textpattern CMS 4.6+. recommended: aks_cache or any part

Nicolas Morand 4 Feb 20, 2020
Tom image grid - Plugin for Textpattern CMS : An optionnal grid display for images tab

tom_image_grid tom_image_grid is a plugin for Textpattern CMS. It allows a more compact display (as a grid) of the images list. The plugin adds two bu

Thomas Jund 5 Jun 30, 2019
This PHP class uploads files and manipulates images very easily

This PHP class uploads files and manipulates images very easily. It is in fact as much as an image processing class than it is an upload class. Compatible with PHP4, 5 and 7. Supports processing of local files, uploaded files, files sent through XMLHttpRequest.

Colin Verot 795 Dec 21, 2022
BreadBooru is a light, quick, and easy to setup imageboard with themes, images, and video support

BreadBooru a bad imageboard, that has nothing to do with (dan/gel)booru, and yet still has booru in the name BreadBooru is a light, quick, and easy to

bread 2 Jan 22, 2022
🐋 This project aims to broaden knowledge of system administration by using Docker: virtualizing several Docker images, creating them in a new personal virtual machine.

?? This project aims to broaden knowledge of system administration by using Docker: virtualizing several Docker images, creating them in a new personal virtual machine.

Anton Kliek 1 Jan 26, 2022
File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery

File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.

Sebastian Tschan 31.1k Dec 30, 2022
Small Library to Serve Images in PHP in a Better Way (Resize, Compress) with Caching Support

A library for serving images and optimizing, changing their sizes, this library uses the caching feature, and in addition, it is very fast and small in size. In addition to these features, this library also optimizes images.

Developix 9 Oct 18, 2022
Create eye-catching Open Graph images for each (or some) site pages

Open Graph Image Generator for Laravel Create Open Graph images (og:image, twitter:image, vk:image) for each (or some) site pages. Use page title to c

Pavel Bychko 4 Nov 11, 2022
Doogle is a search engine and web crawler which can search indexed websites and images

Doogle Doogle is a search engine and web crawler which can search indexed websites and images, and then use keywords to be searched later. Written pri

Zepher Ashe 9 Jan 1, 2023
Images and thumbnails.

Deutsch English Svenska Image 0.8.16 Images and thumbnails. How to add an image Create an [image] shortcut. The following arguments are available, all

Anna 2 Nov 4, 2022