[13.x] Adds first-party support for image processing#59276
[13.x] Adds first-party support for image processing#59276nunomaduro wants to merge 62 commits into13.xfrom
image processing#59276Conversation
This comment was marked as spam.
This comment was marked as spam.
|
Super excited for this! I know you don't want to include a ton of drivers out of the box, but you may want to include libvips support as it is an up and coming performant php extension to replace imagick and gd - https://github.com/libvips/php-vips Glide supports libvips out of the box as of v3 - https://glide.thephpleague.com/3.0/config/image-driver/ |
There was a problem hiding this comment.
How come this isn't using the manager from the support package? I don't see anything in here that would preclude that as an option.
|
While I don't doubt that first-party image manipulation would be nice, having it baked in like this and part of the Image manipulation is a well-known resource hog, consuming memory and CPU like no one's business. If it's going to be added, it should be added as a separate component that you have to deliberately seek out and use, rather than one easily accessed this way. |
Completely agree with this, IMHO this would be really bad to introduce on the request as a native thing from the framework. People are going to read this and use it, without really understanding how it works under the hood, so then Laravel offers a way to do things that have a huge impact on memory and cpu cycles within a request. I get that it's kind of a side-effect of having having access to the Filesystem through a request, but this is quite an impact where all of the implementation is hidden. I feel like this sort of behavior doesn't belong in the |
|
I notice all my comments were marked as resolved, with no answer or changes. Interesting approach. |
|
I think it's better to make the config within the filesystem better than creating a config image. It's just a belief that. |
This PR adds first-party support for image processing in Laravel — a driver-based, immutable API for manipulating images from uploads, storage, file paths, URLs, or raw bytes.
You may also create multiple variants from the same upload.
You may even create thumbnails from existing images — for example, in a queued job.
There’s a lot in this pull request, so bellow is the documentation preview:
Introduction
Laravel provides a powerful, driver-based image processing API that makes it simple to manipulate images from uploads, storage, file paths, or raw bytes. Out of the box, Laravel includes support for processing images via GD, Imagick, and Cloudflare Images.
Configuration
Laravel's image processing configuration file is located at
config/image.php. Within this file, you may configure the default image processing driver as well as driver-specific settings:Note
The
config/image.phpconfiguration file is included by default in new Laravel 13 applications. If your application does not contain this file, you may publish it using theconfig:publishArtisan command:Driver Prerequisites
GD and Imagick Drivers
The GD and Imagick drivers are powered by Intervention Image v3. Before using either driver, you will need to install the Intervention Image package via the Composer package manager:
The GD driver requires the GD PHP extension, while the Imagick driver requires the Imagick PHP extension.
Note
Processing images locally with GD or Imagick can be memory intensive, especially for large images.
Cloudflare Driver
The Cloudflare driver processes images remotely via the Cloudflare Images API. Each image is temporarily uploaded to Cloudflare, transformed via flexible variants, and deleted after the transformed result is downloaded.
Before using the Cloudflare driver, you must enable flexible variants in your Cloudflare dashboard:
Warning
Enabling flexible variants allows anyone with your account's image delivery URL to obtain images with any transformation applied. Do not enable this feature if you rely on variant-based access control for sensitive images.
To use the Cloudflare driver, you will need to set the
IMAGE_CLOUDFLARE_ACCOUNT_IDandIMAGE_CLOUDFLARE_API_TOKENenvironment variables:Warning
Unlike the GD and Imagick drivers, the Cloudflare driver is not memory-intensive because all image processing happens remotely. However, this comes with trade-offs. Each operation requires multiple HTTP requests (uploading, transforming, and deleting), which can make it significantly slower. Additionally, the Cloudflare driver may not produce results that exactly match the original request. While it attempts to follow the specified image transformations, the output can differ in noticeable ways—such as variations in format, encoding, compression, or small discrepancies in dimensions due to rounding.
The Cloudflare driver does not support BMP input images, so when using the Cloudflare driver, ensure your upload validation restricts files to the supported formats:
Pruning Orphaned Images
If the PHP process is terminated during Cloudflare image processing, the temporary image may not be deleted from Cloudflare. You may clean up these orphaned images using the
pruneOrphanedmethod. Images are identified by a configurable prefix (laravel-imageby default) and only images older than 5 minutes are removed. You may schedule this in your application'sroutes/console.phpfile:Obtaining Image Instances
There are several ways to obtain an
Imageinstance. The most common is from an uploaded file on the request:You may also create an image from a file path, a URL, raw bytes, a base64 string, a storage disk, or a Stringable:
Manipulating Images
The
Imageclass provides several methods for common image manipulations. Each method returns a new immutable instance — the original is never modified:coverThe
covermethod resizes and crops the image to exactly fill the given dimensions, maintaining aspect ratio:scaleThe
scalemethod resizes the image proportionally to fit within the given dimensions. Images are never upscaled — if the source is smaller than the target, the original dimensions are preserved:orientThe
orientmethod auto-orients the image based on its EXIF data. This is useful for correcting photos taken on phones that appear rotated:blurThe
blurmethod applies a blur effect to the image. The amount may range from 0 to 100:greyscaleThe
greyscalemethod converts the image to greyscale:sharpenThe
sharpenmethod sharpens the image. This is particularly useful after downscaling, as resized images can appear soft. The amount may range from 0 to 100:flip/flopThe
flipmethod mirrors the image vertically, while theflopmethod mirrors it horizontally:Converting Images
toWebp/toJpgThe
toWebpandtoJpgmethods convert the image to WebP or JPEG format, respectively:qualityThe
qualitymethod sets the output quality for lossy formats. The value should be between 1 and 100:optimizeThe
optimizemethod is a shortcut for setting both the format and quality in a single call:Retrieving Image Information
After processing, you may retrieve information about the resulting image:
The
toBytesmethod returns the raw processed image bytes. ThetoBase64andtoDataUrimethods return encoded representations — useful for inline images or lazy-load placeholders:Storing Images
The
Imageclass provides the same storage methods asUploadedFile. Thestoremethod will store the processed image with a randomly generated filename:Specifying a File Name
If you would like to specify a file name, you may use the
storeAsmethod:Specifying a Disk
You may pass the disk name as the second argument to
store, or as the third argument tostoreAs:Public Visibility
The
storePubliclyandstorePubliclyAsmethods store the image withpublicvisibility:Hash Names
The
hashNamemethod returns a hashed filename with the correct extension based on the processed image's format:Specifying the Driver
By default, images are processed using the driver configured in
config/image.php. You may override the driver for a specific image using theusingmethod or one of the convenience shortcuts:Custom Image Drivers
You may register your own image processing driver using the
extendmethod on theImagefacade. Theextendmethod accepts a driver name and a closure that receives the application instance and should return an implementation ofIlluminate\Contracts\Image\Driver:The
Drivercontract requires a singleprocessmethod: