diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2cbfbb0..168f908 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,6 +19,9 @@ Please review these guidelines before submitting any pull requests. ## 1. Package Development +> ![CAUTION] +> For package testing, both `GD` and `Imagick` drivers must be installed and enabled. + ### Setup Clone your fork, then install the dev dependencies: diff --git a/composer.json b/composer.json index aff01da..ce86bca 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,8 @@ "spatie/laravel-package-tools": "^1.16" }, "require-dev": { + "ext-gd": "*", + "ext-imagick": "*", "larastan/larastan": "^3.0", "laravel/pint": "^1.14", "league/flysystem-aws-s3-v3": "^3.0", diff --git a/docs/pages/available-options.md b/docs/pages/available-options.md index 511ac52..97349f2 100644 --- a/docs/pages/available-options.md +++ b/docs/pages/available-options.md @@ -32,7 +32,7 @@ blur=50 ``` > [!CAUTION] -> The `blur` option is a resource-intensive operation and may cause memory issues if the image is too large. It is recommended to use this option with caution and test beforehand, or disable it in the config. +> 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` diff --git a/docs/pages/installation.md b/docs/pages/installation.md index 779b1d7..c48c23b 100644 --- a/docs/pages/installation.md +++ b/docs/pages/installation.md @@ -4,22 +4,12 @@ - PHP \>= 8.4 - Laravel 12.x -- [GD PHP Library](https://www.php.net/manual/en/book.image.php) +- [GD](https://www.php.net/manual/en/book.image.php) or [Imagick](https://www.php.net/manual/en/book.imagick.php) 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 is required. More info in the [Image Caching](/image-caching) section. ::: -### Important `php.ini` settings❗ -1. The underlying image processing library (GD) can use alot more RAM than regular web requests. It's highly recommended to set your memory limit to *at least* 256MB. -``` -memory_limit=512M -``` -2. If you have the [Swoole extension](https://laravel.com/docs/octane#swoole) installed, make sure 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 -``` - ## Installation Install the package via composer: @@ -33,3 +23,24 @@ Publish the config file with: ```bash php artisan vendor:publish --tag="image-transform-url-config" ``` + +## Driver Configuration + +To use Imagick instead of the default GD library for image processing (recommended for performance), you will have to [change the default image driver](https://image.intervention.io/v3/getting-started/frameworks#application-wide-configuration) for the underlying [Intervention Image](https://image.intervention.io/) package. + +::: info +The [`libvips` driver](https://github.com/Intervention/image-driver-vips) is currently not supported. +::: + +## 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* 256MB. +``` +memory_limit=512M +``` +2. If you have the [Swoole extension](https://laravel.com/docs/octane#swoole) installed, make sure 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 +``` diff --git a/testbench.yaml b/testbench.yaml index 6fcbdfa..a6b2f4e 100644 --- a/testbench.yaml +++ b/testbench.yaml @@ -23,9 +23,6 @@ workbench: config: true build: - asset-publish - - create-sqlite-db - - db-wipe - - migrate-fresh - storage-link assets: - test-assets diff --git a/tests/Feature/CacheTest.php b/tests/Feature/CacheTest.php index c796497..bdf81f1 100644 --- a/tests/Feature/CacheTest.php +++ b/tests/Feature/CacheTest.php @@ -88,7 +88,7 @@ ])); $disk = Storage::disk(config()->string('image-transform-url.cache.disk')); - $size = $disk->size($this->getCacheEndPath('test-data', 'cat.jpg', ['width' => 1200, 'version' => $i])); + $size = $disk->size($this->getCacheEndPath('images', 'cat.jpg', ['width' => 1200, 'version' => $i])); $totalSizeMB += $size / (1024 * 1024); @@ -144,7 +144,7 @@ ])); $disk = Storage::disk(config()->string('image-transform-url.cache.disk')); - $endPath = $this->getCacheEndPath('test-data', 'cat.jpg', ['width' => 1200, 'version' => $i]); + $endPath = $this->getCacheEndPath('images', 'cat.jpg', ['width' => 1200, 'version' => $i]); $cacheFilePaths[] = $endPath; @@ -173,7 +173,7 @@ 'path' => 'cat.jpg', ])); - $lastCacheFilePath = $this->getCacheEndPath('test-data', 'cat.jpg', ['width' => 2400, 'version' => 99]); + $lastCacheFilePath = $this->getCacheEndPath('images', 'cat.jpg', ['width' => 2400, 'version' => 99]); $finalResponse->assertOk(); $finalResponse->assertHeader('X-Cache', 'MISS'); diff --git a/tests/Feature/OptionsTest.php b/tests/Feature/OptionsTest.php index 63ac4e7..e73e2e7 100644 --- a/tests/Feature/OptionsTest.php +++ b/tests/Feature/OptionsTest.php @@ -9,7 +9,18 @@ beforeEach(function () { Cache::flush(); Storage::fake(config()->string('image-transform-url.cache.disk')); -}); +})->with([ + function () { + config()->set('image.driver', \Intervention\Image\Drivers\Gd\Driver::class); + + return 'gd'; + }, + function () { + config()->set('image.driver', \Intervention\Image\Drivers\Imagick\Driver::class); + + return 'imagick'; + }, +]); it('can process the height option', function () { /** @var TestCase $this */ diff --git a/tests/Feature/S3SourceTest.php b/tests/Feature/S3SourceTest.php index 049e8e5..c4ed7e4 100644 --- a/tests/Feature/S3SourceTest.php +++ b/tests/Feature/S3SourceTest.php @@ -21,7 +21,7 @@ it('can serve from an s3 disk source directory', function () { /** @var TestCase $this */ $imagePath = 'images/test.jpg'; - Storage::disk('s3')->put($imagePath, file_get_contents(__DIR__.'/../../workbench/test-data/cat.jpg')); + Storage::disk('s3')->put($imagePath, file_get_contents(public_path('images/cat.jpg'))); $response = $this->get(route('image.transform', [ 'options' => 'width=100', @@ -40,7 +40,7 @@ config()->set('image-transform-url.default_source_directory', 's3'); $imagePath = 'images/test.jpg'; - Storage::disk('s3')->put($imagePath, file_get_contents(__DIR__.'/../../workbench/test-data/cat.jpg')); + Storage::disk('s3')->put($imagePath, file_get_contents(public_path('images/cat.jpg'))); $response = $this->get(route('image.transform.default', [ 'options' => 'width=100', diff --git a/tests/Feature/SignedUrlTest.php b/tests/Feature/SignedUrlTest.php index 4467175..cad8df2 100644 --- a/tests/Feature/SignedUrlTest.php +++ b/tests/Feature/SignedUrlTest.php @@ -16,17 +16,14 @@ function configureTestEnvironment(): void { config()->set('image-transform-url.signed_urls.enabled', true); config()->set('image-transform-url.signed_urls.for_source_directories', ['protected']); - config()->set('image-transform-url.source_directories', [ - 'test-data' => public_path('test-data'), - 'protected' => Storage::fake('local')->path('protected'), - ]); + config()->set('image-transform-url.source_directories.protected', Storage::fake('local')->path('protected')); } it('can protect a route with a signed URL', function () { /** @var TestCase $this */ configureTestEnvironment(); - Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg'))); + Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('images/cat.jpg'))); assert(Storage::disk('local')->exists('protected/cat.jpg')); @@ -53,7 +50,7 @@ function configureTestEnvironment(): void /** @var TestCase $this */ configureTestEnvironment(); - Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg'))); + Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('images/cat.jpg'))); assert(Storage::disk('local')->exists('protected/cat.jpg')); @@ -80,7 +77,7 @@ function configureTestEnvironment(): void /** @var TestCase $this */ configureTestEnvironment(); - Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg'))); + Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('images/cat.jpg'))); assert(Storage::disk('local')->exists('protected/cat.jpg')); @@ -103,7 +100,7 @@ function configureTestEnvironment(): void config()->set('image-transform-url.default_source_directory', 'protected'); - Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg'))); + Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('images/cat.jpg'))); assert(Storage::disk('local')->exists('protected/cat.jpg')); diff --git a/tests/Feature/SourceDirectoriesTest.php b/tests/Feature/SourceDirectoriesTest.php index 77109d7..f7cc565 100644 --- a/tests/Feature/SourceDirectoriesTest.php +++ b/tests/Feature/SourceDirectoriesTest.php @@ -15,7 +15,7 @@ it('can serve from the storage directory', function () { $imagePath = 'images/test.jpg'; - Storage::disk('public')->put($imagePath, file_get_contents(__DIR__.'/../../workbench/test-data/cat.jpg')); + Storage::disk('public')->put($imagePath, file_get_contents(public_path('images/cat.jpg'))); $response = $this->get(route('image.transform', [ 'options' => 'width=100', @@ -34,7 +34,7 @@ config()->set('image-transform-url.default_source_directory', 'storage'); $imagePath = 'images/test.jpg'; - Storage::disk('public')->put($imagePath, file_get_contents(__DIR__.'/../../workbench/test-data/cat.jpg')); + Storage::disk('public')->put($imagePath, file_get_contents(public_path('images/cat.jpg'))); $response = $this->get(route('image.transform.default', [ 'options' => 'width=100', diff --git a/tests/TestCase.php b/tests/TestCase.php index 208ca40..d981d11 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -43,11 +43,7 @@ protected function getEnvironmentSetUp($app) protected function defineEnvironment($app) { tap($app['config'], function (Repository $config) { - $config->set('image-transform-url.source_directories', [ - 'test-data' => public_path('test-data'), - 'storage' => Storage::fake('public')->path(''), - ]); - $config->set('image-transform-url.default_source_directory', 'test-data'); + $config->set('image-transform-url.source_directories.storage', Storage::fake('public')->path('')); $config->set('image-transform-url.enabled_options', AllowedOptions::all()); }); } diff --git a/workbench/app/Providers/WorkbenchServiceProvider.php b/workbench/app/Providers/WorkbenchServiceProvider.php index 5cb54b7..cb30aac 100644 --- a/workbench/app/Providers/WorkbenchServiceProvider.php +++ b/workbench/app/Providers/WorkbenchServiceProvider.php @@ -20,7 +20,7 @@ public function register(): void public function boot(): void { $this->publishes([ - __DIR__.'/../../../workbench/test-data' => public_path('test-data'), + __DIR__.'/../../../workbench/test-data' => public_path('images'), ], 'test-assets'); } } diff --git a/workbench/config/image-transform-url.php b/workbench/config/image-transform-url.php index 60f08db..7b02944 100644 --- a/workbench/config/image-transform-url.php +++ b/workbench/config/image-transform-url.php @@ -19,7 +19,7 @@ */ 'source_directories' => [ - 'images-test' => public_path('images'), + 'images' => public_path('images'), 'storage' => storage_path('app/public/images'), 'remote' => ['disk' => 'r2'], ], @@ -35,7 +35,7 @@ | */ - 'default_source_directory' => env('IMAGE_TRANSFORM_DEFAULT_SOURCE_DIRECTORY', 'images-test'), + 'default_source_directory' => env('IMAGE_TRANSFORM_DEFAULT_SOURCE_DIRECTORY', 'images'), /* |-------------------------------------------------------------------------- diff --git a/workbench/config/image.php b/workbench/config/image.php new file mode 100644 index 0000000..41550ce --- /dev/null +++ b/workbench/config/image.php @@ -0,0 +1,46 @@ + \Intervention\Image\Drivers\Imagick\Driver::class, + + /* + |-------------------------------------------------------------------------- + | Configuration Options + |-------------------------------------------------------------------------- + |There are alifrazimar. + | These options control the behavior of Intervention Image. + | + | - "autoOrientation" controls whether an imported image should be + | automatically rotated according to any existing Exif data. + | + | - "decodeAnimation" decides whether a possibly animated image is + | decoded as such or whether the animation is discarded. + | + | - "blendingColor" Defines the default blending color. + | + | - "strip" controls if meta data like exif tags should be removed when + | encoding images. + */ + + 'options' => [ + 'autoOrientation' => true, + 'decodeAnimation' => true, + 'blendingColor' => 'ffffff', + 'strip' => false, + ], +];