--- url: /available-options.md --- # Available Options These are the options that can be used to transform images with this package. ## `background` `string` Set the background color of the image. Any valid HEX color value (without a leading `#`). Example: ``` background=ff0000 ``` > \[!IMPORTANT] > Only supported for the `png` format. ## `blur` `integer` Set the blur level of the image. Possible values: `0` to `100`. Example: ``` blur=50 ``` > \[!CAUTION] > When using the default GD driver, `blur` is very resource-intensive and may cause memory issues if the image is too large. We recommend the [Imagick driver](/installation#driver-configuration) if you want to use this option, or else to leave it disabled in the config. ## `contrast` `integer` Set the contrast level of the image. Possible values: `-100` to `100`. Example: ``` contrast=50 ``` ## `flip` `string` Flip the image. Possible values: `h` (horizontal), `v` (vertical), `hv` (horizontal and vertical). Example: ``` flip=h ``` ## `format` `string` Set the format of the image. Supported formats: `jpg`, `jpeg`, `png`, `gif`, `webp`. Example: ``` format=webp ``` ## `height` `integer` Set the height of the image. Values greater than the original height will be ignored. Example: ``` height=250 ``` ## `quality` `integer` Set the quality of the image. Possible values: `0` to `100`. Example: ``` quality=80 ``` ## `version` `integer` Version number of the image. Any positive integer. More info in the [Image Caching](/image-caching) section. Example: ``` version=2 ``` ## `width` `integer` Set the width of the image. Values greater than the original width will be ignored. Example: ``` width=250 ``` --- --- url: /configuring-options.md --- # Configuring Options This package supports a variety of options, but you may not need all of them. You can configure which options are enabled in the `image-transform-url.php` configuration file. ```php /* |-------------------------------------------------------------------------- | Enabled Options |-------------------------------------------------------------------------- | | Here you may configure the options which are enabled for the image | transformer. | */ 'enabled_options' => env('IMAGE_TRANSFORM_ENABLED_OPTIONS', [ 'width', 'height', 'format', 'quality', // 'flip', // 'contrast', // 'version', // 'background', // 'blur' ]), ``` --- --- url: /error-handling.md --- # Error Handling The route handler of this package is designed to be robust against invalid options, paths, and file names, while also not exposing additional information about your application's public directory structure. ## HTTP Status Codes For this reason, the route handler returns a plain `404` response if: * the requested image does not exist at the specified path * the requested file is not a valid image * the provided options are not in the correct format (`key=value`, no trailing comma, etc.) The only two other HTTP errors that can be returned are: * a `429` response, which indicates that the request was rate-limited * a `403` response, which indicates that the request was unauthorized (e.g., when using signed URLs and the signature is invalid or expired) ## Invalid options If parts of the given route options are invalid, the route handler ignores them and applies only the valid options. Example: ```ansi http://localhost:8000/image-transform/width=250,quality=foo,format=webp/example.jpg ``` will be processed as: ```ansi http://localhost:8000/image-transform/width=250,format=webp/example.jpg ``` --- --- url: /getting-started.md --- # Getting started Now it's time to test your first image transformation! Use the following URL format to transform your images: ```ansi http://////> ``` > \[!TIP] > You can omit the `` part if you have set a default source directory in the configuration file. For example: ```ansi http://localhost:8000/image-transform/width=250,quality=80,format=webp/foo/bar/example.jpg ``` With a `source-directory`: ```ansi http://localhost:8000/image-transform/images/width=250,quality=80,format=webp/foo/bar/example.jpg ``` ## Programmatic URL Generation While you can construct URLs manually when needed, the package provides convenient methods to generate transformation URLs programmatically using the `ImageTransformUrl` facade. Use the `make()` method to generate regular transformation URLs: ```php use AceOfAces\LaravelImageTransformUrl\Facades\ImageTransformUrl; // Generate a URL with array options $url = ImageTransformUrl::make( path: 'foo/example.jpg', options: ['width' => 250, 'quality' => 80, 'format' => 'webp'], pathPrefix: 'images' ); // Generate a URL with string options $url = ImageTransformUrl::make( path: 'foo/example.jpg', options: 'width=250,quality=80,format=webp', pathPrefix: 'images' ); // Use default source directory (omit the pathPrefix parameter) $url = ImageTransformUrl::make( path: 'foo/example.jpg', options: ['width' => 250, 'quality' => 80] ); ``` The `url()` method is also available as an alias for `make()`: ```php $url = ImageTransformUrl::url( path: 'img/example.jpg', options: ['width' => 250] ); ``` ::: info The facade also provides methods for [generating signed URLs](/signed-urls#generating-signed-urls). ::: --- --- url: /image-caching.md --- # Image Caching This package can automatically store and serve images statically for the requested options within the caching lifetime. > \[!INFO] > Enabling this feature (default) reduces server load and speeds up image delivery. The processed images are stored in the `storage/app/private/_cache/image-transform-url` directory by default. You can change the disk configuration in the `image-transform-url.php` configuration file. > \[!IMPORTANT] > However when using this option, there is one caveat to be aware of: > > **Source images are considered to be stale content by their file name and path.** If the content of a source image changes but the file name stays the same, the cached images will not be updated automatically until the cache expires. To force a revalidation, you can either: 1. change the image's file name 2. move it into another subdirectory, which will change its path 3. change the [version number](/available-options#version) in the options (e.g., `version=2`) 4. or flush the entire cache of your application using the `php artisan cache:clear` command. ## Cache Size Limit The image caching feature also includes a size limit to prevent the cache from growing indefinitely. The default maximum size is **100 MB**, but you can change this in the configuration file. When the cache reaches the specified size limit, it automatically cleans up old files to make space for new ones. You may also configure the percentage of the maximum size that should be kept after cleanup, referred to as `clear_to_percent`. For example, if `clear_to_percent` is set to 80, 20% of the cache is cleared on each cleanup run, and 80% is retained. The default is set to 80% of the maximum size. *** You can configure the caching options in the `image-transform-url.php` configuration file: ```php /* |-------------------------------------------------------------------------- | Image Cache |-------------------------------------------------------------------------- | | Here you may configure the image cache settings. The cache is used to | store the transformed images for a certain amount of time. This is | useful to prevent reprocessing the same image multiple times. | The cache is stored in the configured cache disk. | */ 'cache' => [ 'enabled' => env('IMAGE_TRANSFORM_CACHE_ENABLED', true), 'lifetime' => env('IMAGE_TRANSFORM_CACHE_LIFETIME', 60 * 24 * 7), // 7 days 'disk' => env('IMAGE_TRANSFORM_CACHE_DISK', 'local'), 'max_size_mb' => env('IMAGE_TRANSFORM_CACHE_MAX_SIZE_MB', 100), // 100 MB 'clear_to_percent' => env('IMAGE_TRANSFORM_CACHE_CLEAR_TO_PERCENT', 80), // 80% of max size ], ``` --- --- url: /installation.md --- # Installation ## Requirements * PHP 8.3+ * Laravel 12+ * [GD](https://www.php.net/manual/en/book.image.php), [Imagick](https://www.php.net/manual/en/book.imagick.php) or [Vips (libvips)](https://github.com/libvips/php-vips) PHP extension installed and [enabled](#driver-configuration) ::: tip If you want to use the file caching feature (highly recommended), a configured `Storage` disk and a `Cache` driver are required. More info in the [Image Caching](/image-caching) section. ::: ## Installation Install the package via composer: ```bash composer require ace-of-aces/laravel-image-transform-url ``` Publish the config file with: ```bash php artisan vendor:publish --tag="image-transform-url-config" ``` ## Driver Configuration To use Imagick or Vips instead of the default GD library for image processing (recommended for performance), you must [change the default image driver](https://image.intervention.io/v4/getting-started/frameworks#application-wide-configuration) for the underlying [Intervention Image](https://image.intervention.io/) package. ::: info For the Vips driver option, make sure you have the necessary [Vips driver package for Intervention Image](https://github.com/Intervention/image-driver-vips) installed and configured as default. ::: ## PHP Settings Depending on your environment, you may need to adjust some `php.ini` settings. 1. If you are using the default GD driver, be aware that it can use alot more RAM than regular web requests. It's highly recommended to set your memory limit to *at least* 256 MB. ``` memory_limit=512M ``` 2. If you have the [Swoole extension](https://laravel.com/docs/octane#swoole) installed, ensure you have the following setting to [avoid conflicts](https://github.com/ace-of-aces/laravel-image-transform-url/issues/4) with Laravel's `defer` helper, which this package uses. ``` swoole.use_shortname=off ``` --- --- url: /rate-limiting.md --- # Rate Limiting This package can limit the number of transformations the image transformation route processes **per path and IP address** within a given time frame. The rate limit applies only to new transformation requests and does not affect previously cached images. By default, rate limiting is disabled for the `local` and `testing` app environments so it doesn't distract you during development. You can configure the rate limit settings in the `image-transform-url.php` configuration file. ```php /* |-------------------------------------------------------------------------- | Rate Limit |-------------------------------------------------------------------------- | | Below you may configure the rate limit applied to each image transformation | by path and IP address. It is recommended to set this to a low value, | e.g. 2 requests per minute, to prevent abuse. | */ 'rate_limit' => [ 'enabled' => env('IMAGE_TRANSFORM_RATE_LIMIT_ENABLED', true), 'disabled_for_environments' => [ 'local', 'testing', ], 'max_attempts' => env('IMAGE_TRANSFORM_RATE_LIMIT_MAX_REQUESTS', 2), 'decay_seconds' => env('IMAGE_TRANSFORM_RATE_LIMIT_DECAY_SECONDS', 60), ], ``` --- --- url: /setup.md --- # Setup 1. Configure the package via `image-transform-url.php` to set your `source_directories`, from where you want to transform the images. By default, the package looks for `images` directories in your `public` folder and in the `storage/app/public` directory. 2. Choose a default source directory by setting the `default_source_directory` option in the `image-transform-url.php` configuration file. This is used if no source directory is specified in the URL. > \[!TIP] > It is recommended to use dedicated subdirectories for your images in order to avoid conflicts with other files. An example source directory configuration might look like this: ```php /* |-------------------------------------------------------------------------- | Source Directories |-------------------------------------------------------------------------- | | Here you may configure the directories from which the image transformer | is allowed to serve images. For security reasons, it is recommended | to only allow directories which are already publicly accessible. | | Important: The public storage directory should be addressed directly via | storage('app/public') instead of the public_path('storage') link. | | You can also use any Laravel Filesystem disk (e.g. S3) by providing an | array configuration with 'disk' and an optional 'prefix'. | */ 'source_directories' => [ 'images' => public_path('images'), 'storage' => storage_path('app/public/images'), ], /* |-------------------------------------------------------------------------- | Default Source Directory |-------------------------------------------------------------------------- | | Below you may configure the default source directory which is used when | no specific path prefix is provided in the URL. This should be one of | the keys from the source_directories array. | */ 'default_source_directory' => env('IMAGE_TRANSFORM_DEFAULT_SOURCE_DIRECTORY', 'images'), // ... ``` ## Configuring Remote Sources If you want to use a remote source (like AWS S3 or Cloudflare R2) as a source directory, you may configure any [Laravel Filesystem disk](https://laravel.com/docs/filesystem#configuration) in your `config/filesystems.php` file and then reference it in the `source_directories` configuration. ```php 'source_directories' => [ // Other source directories... 'remote' => [ 'disk' => 's3', // Any valid Laravel Filesystem disk 'prefix' => 'images', // Optional, if you want to specify a subdirectory ], ], ``` Read the [full guide on how to use this package with S3](/s3-usage). --- --- url: /signed-urls.md --- # Signed URLs This package provides the option to generate signed URLs for images from specific source directories powered by [Laravel's URL signing feature](https://laravel.com/docs/urls#signed-urls). This can be useful for securing access to images that should not be publicly accessible without proper authorization or should only be available in a scaled-down version. ::: info Signed URLs also ensure that the provided options cannot be modified client-side. ::: ::: warning The signed URL feature does not restrict access to public images. If you want to secure access to images, ensure that the source directories you want signed URLs for are not publicly accessible. ::: ## Setup To enable signed URLs, set the `signed_urls.enabled` option to `true` in your `image-transform-url.php` configuration. You then need to specify the source directories to which signed URLs should apply in the `signed_urls.for_source_directories` array. For example: ```php 'source_directories' => [ 'images' => public_path('images'), 'protected' => storage_path('app/private/protected-images'), ], // ... 'signed_urls' => [ 'enabled' => env('IMAGE_TRANSFORM_SIGNED_URLS_ENABLED', false), 'for_source_directories' => env('IMAGE_TRANSFORM_SIGNED_URLS_FOR_SOURCE_DIRECTORIES', [ 'protected', ]), ], ``` ## Generating Signed URLs To generate a signed URL for an image, you can use the `ImageTransformUrl` facade: ```php use AceOfAces\LaravelImageTransformUrl\Facades\ImageTransformUrl; $options = [ 'blur' => 50, 'width' => 500, ]; $blurredImage = ImageTransformUrl::signedUrl( path: 'example.jpg', options: $options, pathPrefix: 'protected' ); ``` ## Temporary Signed URLs If you would like to generate a signed URL that expires after a certain time, you can use the `temporarySignedUrl` method: ```php use AceOfAces\LaravelImageTransformUrl\Facades\ImageTransformUrl; $options = [ 'blur' => 50, 'width' => 500, ]; $temporarySignedUrl = ImageTransformUrl::temporarySignedUrl( path: 'example.jpg', options: $options, expiration: now()->addMinutes(60), pathPrefix: 'protected' ); ``` ::: info You can also use the generic `signedUrl` method to generate temporary signed URLs. This method accepts an `$expiration` parameter, which defaults to `null`. If you provide a value, it generates a temporary signed URL. ::: --- --- url: /cdn-usage.md --- # Usage with CDNs The package is designed to work seamlessly with CDNs like Cloudflare, BunnyCDN, and others. The most important configuration is the [`Cache-Control`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) header, which you can customize in the `image-transform-url.php` configuration file. ```php /* |-------------------------------------------------------------------------- | Response Headers |-------------------------------------------------------------------------- | | Below you may configure the response headers which are added to the | response. This is especially useful for controlling caching behavior | of CDNs. | */ 'headers' => [ 'Cache-Control' => env('IMAGE_TRANSFORM_HEADER_CACHE_CONTROL', 'immutable, public, max-age=2592000, s-maxage=2592000'), // more headers can be added here ], ``` --- --- url: /s3-usage.md --- # Usage with S3 This guide explains how to configure this package to work with S3-compatible storage services like AWS S3 or Cloudflare R2. This lets you transform and serve images stored remotely without the need to store them on your local server. 1. Set up your S3 disk in your [filesystems configuration](https://laravel.com/docs/filesystem#amazon-s3-compatible-filesystems), install the [S3 package](https://laravel.com/docs/filesystem#s3-driver-configuration), and ensure you have the necessary credentials and settings for your S3 bucket. Public bucket access is not required. 2. Configure the package via `image-transform-url.php` to include your S3 disk in the `source_directories` as described in [the setup guide](/setup#configuring-remote-sources). 3. If you are using the [Image Caching](/image-caching) feature and want to store transformed images back to your S3 bucket instead of your local filesystem, set the `cache.disk` option in the `image-transform-url.php` configuration file to your S3 disk. ```php 'cache' => [ //... 'disk' => env('IMAGE_TRANSFORM_CACHE_DISK', 's3'), //... ], ``` ::: warning Having the `cache.disk` set to your S3 disk may result in higher latency and costs due to the nature of remote storage. If you are concerned about performance, consider using a local disk for caching and only use S3 for the source directories. ::: 4. You can now use the [image transformation URLs](/getting-started) as usual, and the package will handle fetching images from your S3 bucket.