From 12ec3fb9ba3136ff90bd469883297a5118dfbff1 Mon Sep 17 00:00:00 2001 From: jhorie Date: Tue, 23 Jan 2024 11:58:30 +0100 Subject: [PATCH 01/18] Disabled tiny placeholder generation when use_tiny_placeholder config is disabled --- config/media-library.php | 1 + .../ResponsiveImageGenerator.php | 4 +++ .../ResponsiveImageGeneratorTest.php | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/config/media-library.php b/config/media-library.php index e369db782..bace6c88e 100644 --- a/config/media-library.php +++ b/config/media-library.php @@ -225,6 +225,7 @@ /* * By default rendering media to a responsive image will add some javascript and a tiny placeholder. * This ensures that the browser can already determine the correct layout. + * When disabled, no tiny placeholder is generated. */ 'use_tiny_placeholders' => true, diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index 8560377ab..cababc454 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -117,6 +117,10 @@ public function generateTinyJpg( string $conversionName, BaseTemporaryDirectory $temporaryDirectory ): void { + if (! config('media-library.responsive_images.use_tiny_placeholders')) { + return; + } + $tempDestination = $temporaryDirectory->path('tiny.jpg'); $this->tinyPlaceholderGenerator->generateTinyPlaceholder($originalImagePath, $tempDestination); diff --git a/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php b/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php index 2496614db..297509fda 100644 --- a/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php +++ b/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php @@ -86,3 +86,29 @@ $this->artisan('media-library:regenerate'); expect($media->fresh()->responsive_images['thumb']['urls'])->toHaveCount(1); }); + +it('will generate tiny placeholders when tiny placeholders are turned on', function () { + $media = $this->testModelWithConversion + ->addMedia($this->getTestJpg()) + ->withResponsiveImages() + ->toMediaCollection(); + + $responsiveImage = $media->refresh()->responsive_images; + + expect($responsiveImage['media_library_original'])->toHaveKey('base64svg'); + + expect((string) $responsiveImage['media_library_original']['base64svg'])->toContain('data:image/svg+xml;base64,'); +}); + +it('will not generate tiny placeholders when tiny placeholders are turned off', function () { + config()->set('media-library.responsive_images.use_tiny_placeholders', false); + + $media = $this->testModelWithConversion + ->addMedia($this->getTestJpg()) + ->withResponsiveImages() + ->toMediaCollection(); + + $responsiveImage = $media->refresh()->responsive_images; + + expect($responsiveImage['media_library_original'])->not()->toHaveKey('base64svg'); +}); From f102ebf05d2008218f1a18d8254256085c13b5eb Mon Sep 17 00:00:00 2001 From: jhorie Date: Tue, 23 Jan 2024 14:46:33 +0100 Subject: [PATCH 02/18] Conversion specific Width Calculator is supported --- src/Conversions/Conversion.php | 15 +++++++ .../ResponsiveImageGenerator.php | 4 +- .../MaxWidthWidthCalculator.php | 45 +++++++++++++++++++ .../ResponsiveImages/ResponsiveImageTest.php | 21 +++++++++ .../TestModelWithResponsiveImages.php | 8 ++++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index 52c3c1da0..a8b62d7c2 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -6,6 +6,7 @@ use Illuminate\Support\Traits\Conditionable; use Spatie\ImageOptimizer\OptimizerChainFactory; use Spatie\MediaLibrary\MediaCollections\Models\Media; +use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator; use Spatie\MediaLibrary\Support\FileNamer\FileNamer; /** @mixin \Spatie\Image\Drivers\ImageDriver */ @@ -27,6 +28,8 @@ class Conversion protected bool $generateResponsiveImages = false; + protected WidthCalculator|null $widthCalculator = null; + protected ?string $loadingAttributeValue; protected int $pdfPageNumber = 1; @@ -190,6 +193,18 @@ public function withResponsiveImages(): self return $this; } + public function withWidthCalculator(WidthCalculator $widthCalculator): self + { + $this->widthCalculator = $widthCalculator; + + return $this; + } + + public function getWidthCalculator(): WidthCalculator | null + { + return $this->widthCalculator; + } + public function shouldGenerateResponsiveImages(): bool { return $this->generateResponsiveImages; diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index cababc454..0f39cc448 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -58,7 +58,9 @@ public function generateResponsiveImagesForConversion(Media $media, Conversion $ $media = $this->cleanResponsiveImages($media, $conversion->getName()); - foreach ($this->widthCalculator->calculateWidthsFromFile($baseImage) as $width) { + $widthCalculator = $conversion->getWidthCalculator() ?? $this->widthCalculator; + + foreach ($widthCalculator->calculateWidthsFromFile($baseImage) as $width) { $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion)); } diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php new file mode 100644 index 000000000..b6e87032b --- /dev/null +++ b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php @@ -0,0 +1,45 @@ +getWidth(); + $height = $image->getHeight(); + $fileSize = filesize($imagePath); + + return $this->calculateWidths($fileSize, $width, $height); + } + + public function calculateWidths(int $fileSize, int $width, int $height): Collection + { + $targetWidths = collect(); + + $width = min($this->maxWidth, $width); + + $targetWidths->push($width); + + while (true) { + $width = (int) $width * 0.6; + + if ($width <= 20) { + return $targetWidths; + } + + $targetWidths->push($width); + } + } + +} diff --git a/tests/ResponsiveImages/ResponsiveImageTest.php b/tests/ResponsiveImages/ResponsiveImageTest.php index 66cf6e560..a1967fcdd 100644 --- a/tests/ResponsiveImages/ResponsiveImageTest.php +++ b/tests/ResponsiveImages/ResponsiveImageTest.php @@ -112,3 +112,24 @@ expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); }); + +it('can use some other width calculator for a conversion', function () { + $this + ->testModelWithResponsiveImages + ->addMedia($this->getTestJpg()) + ->toMediaCollection("customWidthCalculator"); + + $media = $this->testModelWithResponsiveImages->getFirstMedia("customWidthCalculator"); + + $this->assertSame([ + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_200_165.jpg", + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_80_66.jpg", + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_32_26.jpg", + ], $media->getResponsiveImageUrls("customWidthCalculator")); + + $this->assertSame([ + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__thumb_50_41.jpg", + ], $media->getResponsiveImageUrls('thumb')); + + expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); +}); diff --git a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php index 40e574db8..9dc11457e 100644 --- a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php +++ b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php @@ -3,6 +3,7 @@ namespace Spatie\MediaLibrary\Tests\TestSupport\TestModels; use Spatie\MediaLibrary\MediaCollections\Models\Media; +use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\MaxWidthWidthCalculator; class TestModelWithResponsiveImages extends TestModel { @@ -36,5 +37,12 @@ public function registerMediaConversions(?Media $media = null): void ->addMediaConversion('standardQuality') ->withResponsiveImages() ->nonQueued(); + + + $this + ->addMediaConversion('customWidthCalculator') + ->withResponsiveImages() + ->withWidthCalculator(new MaxWidthWidthCalculator(200)) + ->nonQueued(); } } From 2864d0b0c5c8b575c05e3a17a6db8c8d7a2bbf3c Mon Sep 17 00:00:00 2001 From: jhorie Date: Tue, 23 Jan 2024 14:50:41 +0100 Subject: [PATCH 03/18] Conversion specific Width Calculator is supported --- .../WidthCalculator/MaxWidthWidthCalculator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php index b6e87032b..1bb45a7e7 100644 --- a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php +++ b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php @@ -8,7 +8,7 @@ class MaxWidthWidthCalculator implements WidthCalculator { - public function __construct(public array $maxWidth) + public function __construct(public int $maxWidth) { } From 8a4f79e9442909c56a03f81d46fdd6608e4458b8 Mon Sep 17 00:00:00 2001 From: jhorie Date: Wed, 24 Jan 2024 09:22:36 +0100 Subject: [PATCH 04/18] Revert "Conversion specific Width Calculator is supported" This reverts commit 2864d0b0c5c8b575c05e3a17a6db8c8d7a2bbf3c. --- .../WidthCalculator/MaxWidthWidthCalculator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php index 1bb45a7e7..b6e87032b 100644 --- a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php +++ b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php @@ -8,7 +8,7 @@ class MaxWidthWidthCalculator implements WidthCalculator { - public function __construct(public int $maxWidth) + public function __construct(public array $maxWidth) { } From 00911c5801036e308201365c2c41e4f86c8c3de6 Mon Sep 17 00:00:00 2001 From: jhorie Date: Wed, 24 Jan 2024 09:22:36 +0100 Subject: [PATCH 05/18] Revert "Conversion specific Width Calculator is supported" This reverts commit f102ebf05d2008218f1a18d8254256085c13b5eb. --- src/Conversions/Conversion.php | 15 ------- .../ResponsiveImageGenerator.php | 4 +- .../MaxWidthWidthCalculator.php | 45 ------------------- .../ResponsiveImages/ResponsiveImageTest.php | 21 --------- .../TestModelWithResponsiveImages.php | 8 ---- 5 files changed, 1 insertion(+), 92 deletions(-) delete mode 100644 src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index a8b62d7c2..52c3c1da0 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -6,7 +6,6 @@ use Illuminate\Support\Traits\Conditionable; use Spatie\ImageOptimizer\OptimizerChainFactory; use Spatie\MediaLibrary\MediaCollections\Models\Media; -use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator; use Spatie\MediaLibrary\Support\FileNamer\FileNamer; /** @mixin \Spatie\Image\Drivers\ImageDriver */ @@ -28,8 +27,6 @@ class Conversion protected bool $generateResponsiveImages = false; - protected WidthCalculator|null $widthCalculator = null; - protected ?string $loadingAttributeValue; protected int $pdfPageNumber = 1; @@ -193,18 +190,6 @@ public function withResponsiveImages(): self return $this; } - public function withWidthCalculator(WidthCalculator $widthCalculator): self - { - $this->widthCalculator = $widthCalculator; - - return $this; - } - - public function getWidthCalculator(): WidthCalculator | null - { - return $this->widthCalculator; - } - public function shouldGenerateResponsiveImages(): bool { return $this->generateResponsiveImages; diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index 0f39cc448..cababc454 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -58,9 +58,7 @@ public function generateResponsiveImagesForConversion(Media $media, Conversion $ $media = $this->cleanResponsiveImages($media, $conversion->getName()); - $widthCalculator = $conversion->getWidthCalculator() ?? $this->widthCalculator; - - foreach ($widthCalculator->calculateWidthsFromFile($baseImage) as $width) { + foreach ($this->widthCalculator->calculateWidthsFromFile($baseImage) as $width) { $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion)); } diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php deleted file mode 100644 index b6e87032b..000000000 --- a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php +++ /dev/null @@ -1,45 +0,0 @@ -getWidth(); - $height = $image->getHeight(); - $fileSize = filesize($imagePath); - - return $this->calculateWidths($fileSize, $width, $height); - } - - public function calculateWidths(int $fileSize, int $width, int $height): Collection - { - $targetWidths = collect(); - - $width = min($this->maxWidth, $width); - - $targetWidths->push($width); - - while (true) { - $width = (int) $width * 0.6; - - if ($width <= 20) { - return $targetWidths; - } - - $targetWidths->push($width); - } - } - -} diff --git a/tests/ResponsiveImages/ResponsiveImageTest.php b/tests/ResponsiveImages/ResponsiveImageTest.php index a1967fcdd..66cf6e560 100644 --- a/tests/ResponsiveImages/ResponsiveImageTest.php +++ b/tests/ResponsiveImages/ResponsiveImageTest.php @@ -112,24 +112,3 @@ expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); }); - -it('can use some other width calculator for a conversion', function () { - $this - ->testModelWithResponsiveImages - ->addMedia($this->getTestJpg()) - ->toMediaCollection("customWidthCalculator"); - - $media = $this->testModelWithResponsiveImages->getFirstMedia("customWidthCalculator"); - - $this->assertSame([ - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_200_165.jpg", - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_80_66.jpg", - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_32_26.jpg", - ], $media->getResponsiveImageUrls("customWidthCalculator")); - - $this->assertSame([ - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__thumb_50_41.jpg", - ], $media->getResponsiveImageUrls('thumb')); - - expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); -}); diff --git a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php index 9dc11457e..40e574db8 100644 --- a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php +++ b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php @@ -3,7 +3,6 @@ namespace Spatie\MediaLibrary\Tests\TestSupport\TestModels; use Spatie\MediaLibrary\MediaCollections\Models\Media; -use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\MaxWidthWidthCalculator; class TestModelWithResponsiveImages extends TestModel { @@ -37,12 +36,5 @@ public function registerMediaConversions(?Media $media = null): void ->addMediaConversion('standardQuality') ->withResponsiveImages() ->nonQueued(); - - - $this - ->addMediaConversion('customWidthCalculator') - ->withResponsiveImages() - ->withWidthCalculator(new MaxWidthWidthCalculator(200)) - ->nonQueued(); } } From 0d1edbc9765066568678e392f3de636480b9eb9b Mon Sep 17 00:00:00 2001 From: jhorie Date: Sat, 27 Jan 2024 17:43:47 +0100 Subject: [PATCH 06/18] Revert "Revert "Conversion specific Width Calculator is supported"" This reverts commit 00911c5801036e308201365c2c41e4f86c8c3de6. --- src/Conversions/Conversion.php | 15 +++++++ .../ResponsiveImageGenerator.php | 4 +- .../MaxWidthWidthCalculator.php | 45 +++++++++++++++++++ .../ResponsiveImages/ResponsiveImageTest.php | 21 +++++++++ .../TestModelWithResponsiveImages.php | 8 ++++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index 52c3c1da0..a8b62d7c2 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -6,6 +6,7 @@ use Illuminate\Support\Traits\Conditionable; use Spatie\ImageOptimizer\OptimizerChainFactory; use Spatie\MediaLibrary\MediaCollections\Models\Media; +use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\WidthCalculator; use Spatie\MediaLibrary\Support\FileNamer\FileNamer; /** @mixin \Spatie\Image\Drivers\ImageDriver */ @@ -27,6 +28,8 @@ class Conversion protected bool $generateResponsiveImages = false; + protected WidthCalculator|null $widthCalculator = null; + protected ?string $loadingAttributeValue; protected int $pdfPageNumber = 1; @@ -190,6 +193,18 @@ public function withResponsiveImages(): self return $this; } + public function withWidthCalculator(WidthCalculator $widthCalculator): self + { + $this->widthCalculator = $widthCalculator; + + return $this; + } + + public function getWidthCalculator(): WidthCalculator | null + { + return $this->widthCalculator; + } + public function shouldGenerateResponsiveImages(): bool { return $this->generateResponsiveImages; diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index cababc454..0f39cc448 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -58,7 +58,9 @@ public function generateResponsiveImagesForConversion(Media $media, Conversion $ $media = $this->cleanResponsiveImages($media, $conversion->getName()); - foreach ($this->widthCalculator->calculateWidthsFromFile($baseImage) as $width) { + $widthCalculator = $conversion->getWidthCalculator() ?? $this->widthCalculator; + + foreach ($widthCalculator->calculateWidthsFromFile($baseImage) as $width) { $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion)); } diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php new file mode 100644 index 000000000..b6e87032b --- /dev/null +++ b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php @@ -0,0 +1,45 @@ +getWidth(); + $height = $image->getHeight(); + $fileSize = filesize($imagePath); + + return $this->calculateWidths($fileSize, $width, $height); + } + + public function calculateWidths(int $fileSize, int $width, int $height): Collection + { + $targetWidths = collect(); + + $width = min($this->maxWidth, $width); + + $targetWidths->push($width); + + while (true) { + $width = (int) $width * 0.6; + + if ($width <= 20) { + return $targetWidths; + } + + $targetWidths->push($width); + } + } + +} diff --git a/tests/ResponsiveImages/ResponsiveImageTest.php b/tests/ResponsiveImages/ResponsiveImageTest.php index 66cf6e560..a1967fcdd 100644 --- a/tests/ResponsiveImages/ResponsiveImageTest.php +++ b/tests/ResponsiveImages/ResponsiveImageTest.php @@ -112,3 +112,24 @@ expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); }); + +it('can use some other width calculator for a conversion', function () { + $this + ->testModelWithResponsiveImages + ->addMedia($this->getTestJpg()) + ->toMediaCollection("customWidthCalculator"); + + $media = $this->testModelWithResponsiveImages->getFirstMedia("customWidthCalculator"); + + $this->assertSame([ + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_200_165.jpg", + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_80_66.jpg", + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_32_26.jpg", + ], $media->getResponsiveImageUrls("customWidthCalculator")); + + $this->assertSame([ + "/media/1/responsive-images/{$this->fileNameWithUnderscore}__thumb_50_41.jpg", + ], $media->getResponsiveImageUrls('thumb')); + + expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); +}); diff --git a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php index 40e574db8..9dc11457e 100644 --- a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php +++ b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php @@ -3,6 +3,7 @@ namespace Spatie\MediaLibrary\Tests\TestSupport\TestModels; use Spatie\MediaLibrary\MediaCollections\Models\Media; +use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\MaxWidthWidthCalculator; class TestModelWithResponsiveImages extends TestModel { @@ -36,5 +37,12 @@ public function registerMediaConversions(?Media $media = null): void ->addMediaConversion('standardQuality') ->withResponsiveImages() ->nonQueued(); + + + $this + ->addMediaConversion('customWidthCalculator') + ->withResponsiveImages() + ->withWidthCalculator(new MaxWidthWidthCalculator(200)) + ->nonQueued(); } } From ecc9afc99a51f23fa7462c24439e28860ce00c73 Mon Sep 17 00:00:00 2001 From: jhorie Date: Sat, 27 Jan 2024 18:21:36 +0100 Subject: [PATCH 07/18] CustomWidthCalculator --- .../MaxWidthWidthCalculator.php | 45 ------------------- .../ConversionCustomWidthCalculator.php | 41 +++++++++++++++++ .../TestModelWithResponsiveImages.php | 8 ---- .../WidthCalculators/FixedWidthCalculator.php | 23 ++++++++++ 4 files changed, 64 insertions(+), 53 deletions(-) delete mode 100644 src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php create mode 100644 tests/Conversions/ConversionCustomWidthCalculator.php create mode 100644 tests/TestSupport/WidthCalculators/FixedWidthCalculator.php diff --git a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php b/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php deleted file mode 100644 index b6e87032b..000000000 --- a/src/ResponsiveImages/WidthCalculator/MaxWidthWidthCalculator.php +++ /dev/null @@ -1,45 +0,0 @@ -getWidth(); - $height = $image->getHeight(); - $fileSize = filesize($imagePath); - - return $this->calculateWidths($fileSize, $width, $height); - } - - public function calculateWidths(int $fileSize, int $width, int $height): Collection - { - $targetWidths = collect(); - - $width = min($this->maxWidth, $width); - - $targetWidths->push($width); - - while (true) { - $width = (int) $width * 0.6; - - if ($width <= 20) { - return $targetWidths; - } - - $targetWidths->push($width); - } - } - -} diff --git a/tests/Conversions/ConversionCustomWidthCalculator.php b/tests/Conversions/ConversionCustomWidthCalculator.php new file mode 100644 index 000000000..cb6f7e470 --- /dev/null +++ b/tests/Conversions/ConversionCustomWidthCalculator.php @@ -0,0 +1,41 @@ +addMediaConversion('fixed_width')->withWidthCalculator(new FixedWidthCalculator([99, 60, 33]))->withResponsiveImages(); + } + })::create(['name' => 'test.jpg']);; + + $testModel5Sizes = (new class() extends TestModel { + public function registerMediaConversions(?Media $media = null): void + { + $this->addMediaConversion('fixed_width')->withWidthCalculator(new FixedWidthCalculator([76, 59, 44, 23, 11]))->withResponsiveImages(); + } + })::create(['name' => 'test.png']); + + $testModel3Sizes->addMedia($this->getTestJpg())->toMediaCollection(); + + $this->assertSame([ + "/media/1/responsive-images/test___fixed_width_99_82.jpg", + "/media/1/responsive-images/test___fixed_width_60_49.jpg", + "/media/1/responsive-images/test___fixed_width_33_27.jpg", + ], $testModel3Sizes->getFirstMedia()->getResponsiveImageUrls("fixed_width")); + + + $testModel5Sizes->addMedia($this->getTestPng())->toMediaCollection(); + + $this->assertSame([ + "/media/2/responsive-images/test___fixed_width_76_96.jpg", + "/media/2/responsive-images/test___fixed_width_59_74.jpg", + "/media/2/responsive-images/test___fixed_width_44_56.jpg", + "/media/2/responsive-images/test___fixed_width_23_29.jpg", + "/media/2/responsive-images/test___fixed_width_11_14.jpg", + ], $testModel5Sizes->getFirstMedia()->getResponsiveImageUrls("fixed_width")); +}); diff --git a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php index 9dc11457e..40e574db8 100644 --- a/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php +++ b/tests/TestSupport/TestModels/TestModelWithResponsiveImages.php @@ -3,7 +3,6 @@ namespace Spatie\MediaLibrary\Tests\TestSupport\TestModels; use Spatie\MediaLibrary\MediaCollections\Models\Media; -use Spatie\MediaLibrary\ResponsiveImages\WidthCalculator\MaxWidthWidthCalculator; class TestModelWithResponsiveImages extends TestModel { @@ -37,12 +36,5 @@ public function registerMediaConversions(?Media $media = null): void ->addMediaConversion('standardQuality') ->withResponsiveImages() ->nonQueued(); - - - $this - ->addMediaConversion('customWidthCalculator') - ->withResponsiveImages() - ->withWidthCalculator(new MaxWidthWidthCalculator(200)) - ->nonQueued(); } } diff --git a/tests/TestSupport/WidthCalculators/FixedWidthCalculator.php b/tests/TestSupport/WidthCalculators/FixedWidthCalculator.php new file mode 100644 index 000000000..08a919a8a --- /dev/null +++ b/tests/TestSupport/WidthCalculators/FixedWidthCalculator.php @@ -0,0 +1,23 @@ +calculateWidths(0, 0, 0); + } + + public function calculateWidths(int $fileSize, int $width, int $height): Collection + { + return collect($this->widths); + } +} From 4ddb6b471de0330649b7d009fe2268d02d165132 Mon Sep 17 00:00:00 2001 From: jhorie Date: Sat, 27 Jan 2024 18:24:31 +0100 Subject: [PATCH 08/18] CustomWidthCalculator --- .../ResponsiveImages/ResponsiveImageTest.php | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/tests/ResponsiveImages/ResponsiveImageTest.php b/tests/ResponsiveImages/ResponsiveImageTest.php index a1967fcdd..66cf6e560 100644 --- a/tests/ResponsiveImages/ResponsiveImageTest.php +++ b/tests/ResponsiveImages/ResponsiveImageTest.php @@ -112,24 +112,3 @@ expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); }); - -it('can use some other width calculator for a conversion', function () { - $this - ->testModelWithResponsiveImages - ->addMedia($this->getTestJpg()) - ->toMediaCollection("customWidthCalculator"); - - $media = $this->testModelWithResponsiveImages->getFirstMedia("customWidthCalculator"); - - $this->assertSame([ - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_200_165.jpg", - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_80_66.jpg", - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__customWidthCalculator_32_26.jpg", - ], $media->getResponsiveImageUrls("customWidthCalculator")); - - $this->assertSame([ - "/media/1/responsive-images/{$this->fileNameWithUnderscore}__thumb_50_41.jpg", - ], $media->getResponsiveImageUrls('thumb')); - - expect($media->getResponsiveImageUrls('non-existing-conversion'))->toBe([]); -}); From 94b97f6e744ab5f1dcb10db16f18a9bff5e06bae Mon Sep 17 00:00:00 2001 From: jhorie Date: Sat, 27 Jan 2024 18:26:21 +0100 Subject: [PATCH 09/18] CustomWidthCalculator --- tests/Conversions/ConversionCustomWidthCalculator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Conversions/ConversionCustomWidthCalculator.php b/tests/Conversions/ConversionCustomWidthCalculator.php index cb6f7e470..3d8f6c672 100644 --- a/tests/Conversions/ConversionCustomWidthCalculator.php +++ b/tests/Conversions/ConversionCustomWidthCalculator.php @@ -5,7 +5,7 @@ use Spatie\MediaLibrary\Tests\TestSupport\TestModels\TestModel; use Spatie\MediaLibrary\Tests\TestSupport\WidthCalculators\FixedWidthCalculator; -it('can use some other width calculator for a conversion', function () { +it('can utilize various width calculators for conversions across different models', function () { $testModel3Sizes = (new class() extends TestModel { public function registerMediaConversions(?Media $media = null): void { From 5cefd229f557212de0ccadfd0207598d216c1ba2 Mon Sep 17 00:00:00 2001 From: jhorie Date: Sat, 27 Jan 2024 18:30:30 +0100 Subject: [PATCH 10/18] CustomWidthCalculator --- src/Conversions/Conversion.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index a8b62d7c2..d19a46de2 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -28,7 +28,7 @@ class Conversion protected bool $generateResponsiveImages = false; - protected WidthCalculator|null $widthCalculator = null; + protected ?WidthCalculator $widthCalculator = null; protected ?string $loadingAttributeValue; @@ -200,7 +200,7 @@ public function withWidthCalculator(WidthCalculator $widthCalculator): self return $this; } - public function getWidthCalculator(): WidthCalculator | null + public function getWidthCalculator(): ?WidthCalculator { return $this->widthCalculator; } From 8b7d0f50c8042f9e4eca9b6849c0d7d2ff45b275 Mon Sep 17 00:00:00 2001 From: jhorie Date: Thu, 1 Feb 2024 08:37:22 +0100 Subject: [PATCH 11/18] gif2webp && mmpeg --- config/media-library.php | 2 + .../Actions/PerformConversionAction.php | 19 ++++++++- .../Actions/PerformManipulationsAction.php | 10 +++++ src/Conversions/Conversion.php | 17 +++++++++ src/Conversions/ImageGenerators/Video.php | 4 ++ .../ResponsiveImageGenerator.php | 13 +++++-- .../ResponsiveImageGeneratorTest.php | 36 ++++++++++++++++++ tests/TestCase.php | 5 +++ tests/TestSupport/testfiles/test.gif | Bin 0 -> 109693 bytes 9 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 tests/TestSupport/testfiles/test.gif diff --git a/config/media-library.php b/config/media-library.php index bace6c88e..5f91db646 100644 --- a/config/media-library.php +++ b/config/media-library.php @@ -259,4 +259,6 @@ * If you set this to `/my-subdir`, all your media will be stored in a `/my-subdir` directory. */ 'prefix' => env('MEDIA_PREFIX', ''), + + 'convert_gif_to_webp_using_gif2webp' => false, ]; diff --git a/src/Conversions/Actions/PerformConversionAction.php b/src/Conversions/Actions/PerformConversionAction.php index d134aef66..20c314d04 100644 --- a/src/Conversions/Actions/PerformConversionAction.php +++ b/src/Conversions/Actions/PerformConversionAction.php @@ -2,6 +2,7 @@ namespace Spatie\MediaLibrary\Conversions\Actions; +use Illuminate\Support\Str; use Spatie\MediaLibrary\Conversions\Conversion; use Spatie\MediaLibrary\Conversions\Events\ConversionHasBeenCompletedEvent; use Spatie\MediaLibrary\Conversions\Events\ConversionWillStartEvent; @@ -25,6 +26,14 @@ public function execute( return; } + $shouldUseGif2WebpConverter = config('media-library.convert_gif_to_webp_using_gif2webp') + && pathinfo($copiedOriginalFile, PATHINFO_EXTENSION) === "gif" + && $conversion->getManipulations()->getManipulationArgument('format') == ["webp"]; + + if ($shouldUseGif2WebpConverter) { + $conversion->setUseGif2WebpAsConverter(); + } + event(new ConversionWillStartEvent($media, $conversion, $copiedOriginalFile)); $manipulationResult = (new PerformManipulationsAction())->execute($media, $conversion, $copiedOriginalFile); @@ -33,6 +42,13 @@ public function execute( $renamedFile = $this->renameInLocalDirectory($manipulationResult, $newFileName); + $manipulatedFile = $renamedFile; + if ($shouldUseGif2WebpConverter) { + $manipulatedFile = pathinfo($renamedFile, PATHINFO_DIRNAME) . '/' . (Str::random(32) . '.' . $media->extension); + copy($renamedFile, $manipulatedFile); + exec("gif2webp " . $renamedFile . " -o " . $renamedFile); + } + if ($conversion->shouldGenerateResponsiveImages()) { /** @var ResponsiveImageGenerator $responsiveImageGenerator */ $responsiveImageGenerator = app(ResponsiveImageGenerator::class); @@ -40,7 +56,8 @@ public function execute( $responsiveImageGenerator->generateResponsiveImagesForConversion( $media, $conversion, - $renamedFile + $manipulatedFile, + $shouldUseGif2WebpConverter ); } diff --git a/src/Conversions/Actions/PerformManipulationsAction.php b/src/Conversions/Actions/PerformManipulationsAction.php index 037c26b0a..4aba2201d 100644 --- a/src/Conversions/Actions/PerformManipulationsAction.php +++ b/src/Conversions/Actions/PerformManipulationsAction.php @@ -30,6 +30,15 @@ public function execute( $conversion->format($media->extension); } + if (Str::startsWith(File::mimeType($conversionTempFile), "video/") && $conversion->getManipulations()->getManipulationArgument('format') == "webm") { + exec("ffmpeg -i " . $conversionTempFile . " -f webm -an " . $conversionTempFile . ".webm"); + if (File::exists($conversionTempFile . '.webm')) { + unlink($conversionTempFile); + rename($conversionTempFile . '.webm', $conversionTempFile); + } else { + throw new \RuntimeException("Converted webm file does not exist, check if ffmpeg is intalled!"); + } + } else { $image = Image::useImageDriver(config('media-library.image_driver')) ->loadFile($conversionTempFile) ->format('jpg'); @@ -40,6 +49,7 @@ public function execute( $image->save(); } catch (UnsupportedImageFormat) { + } } return $conversionTempFile; diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index d19a46de2..a83ad3bd6 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -34,6 +34,8 @@ class Conversion protected int $pdfPageNumber = 1; + protected bool $useGif2Webp = false; + public function __construct( protected string $name, ) { @@ -92,6 +94,17 @@ public function shouldKeepOriginalImageFormat(): bool return $this->keepOriginalImageFormat; } + public function setUseGif2WebpAsConverter(): void + { + $this->useGif2Webp = true; + $this->removeManipulation('format'); + } + + public function shouldUseGif2WebpAsConverter(): bool + { + return $this->useGif2Webp; + } + public function getManipulations(): Manipulations { return $this->manipulations; @@ -223,6 +236,10 @@ public function getResultExtension(string $originalFileExtension = ''): string } } + if ($this->shouldUseGif2WebpAsConverter()) { + return "webp"; + } + if ($manipulationArgument = Arr::get($this->manipulations->getManipulationArgument('format'), 0)) { return $manipulationArgument; } diff --git a/src/Conversions/ImageGenerators/Video.php b/src/Conversions/ImageGenerators/Video.php index 47d7c76c2..762505848 100644 --- a/src/Conversions/ImageGenerators/Video.php +++ b/src/Conversions/ImageGenerators/Video.php @@ -12,6 +12,10 @@ class Video extends ImageGenerator { public function convert(string $file, ?Conversion $conversion = null): ?string { + if ($conversion->getManipulations()->getManipulationArgument('format') == "webm") { + return $file; + } + $ffmpeg = FFMpeg::create([ 'ffmpeg.binaries' => config('media-library.ffmpeg_path'), 'ffprobe.binaries' => config('media-library.ffprobe_path'), diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index 0f39cc448..0321a2b0a 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -52,7 +52,7 @@ public function generateResponsiveImages(Media $media): void $temporaryDirectory->delete(); } - public function generateResponsiveImagesForConversion(Media $media, Conversion $conversion, string $baseImage): void + public function generateResponsiveImagesForConversion(Media $media, Conversion $conversion, string $baseImage, bool $shouldUseGif2WebpConverter): void { $temporaryDirectory = TemporaryDirectory::create(); @@ -61,7 +61,7 @@ public function generateResponsiveImagesForConversion(Media $media, Conversion $ $widthCalculator = $conversion->getWidthCalculator() ?? $this->widthCalculator; foreach ($widthCalculator->calculateWidthsFromFile($baseImage) as $width) { - $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion)); + $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion), $shouldUseGif2WebpConverter); } $this->generateTinyJpg($media, $baseImage, $conversion->getName(), $temporaryDirectory); @@ -80,7 +80,8 @@ public function generateResponsiveImage( string $conversionName, int $targetWidth, BaseTemporaryDirectory $temporaryDirectory, - int $conversionQuality = self::DEFAULT_CONVERSION_QUALITY + int $conversionQuality = self::DEFAULT_CONVERSION_QUALITY, + bool $shouldUseGif2WebpConverter = false ): void { $extension = $this->fileNamer->extensionFromBaseImage($baseImage); $responsiveImagePath = $this->fileNamer->temporaryFileName($media, $extension); @@ -101,13 +102,17 @@ public function generateResponsiveImage( $conversionName, $targetWidth, $responsiveImageHeight, - $extension + $shouldUseGif2WebpConverter ? "webp" : $extension ); $responsiveImagePath = $temporaryDirectory->path($fileName); rename($tempDestination, $responsiveImagePath); + if ($shouldUseGif2WebpConverter) { + exec("gif2webp " . $responsiveImagePath . " -o " . $responsiveImagePath); + } + $this->filesystem->copyToMediaLibrary($responsiveImagePath, $media, 'responsiveImages'); ResponsiveImage::register($media, $fileName, $conversionName); diff --git a/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php b/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php index 297509fda..853fc638d 100644 --- a/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php +++ b/tests/ResponsiveImages/ResponsiveImageGeneratorTest.php @@ -1,7 +1,10 @@ fileName = 'test'; @@ -112,3 +115,36 @@ expect($responsiveImage['media_library_original'])->not()->toHaveKey('base64svg'); }); + +it('can generate responsive animated images', function (string $driver) { + config()->set('media-library.image_driver', $driver); + config()->set('media-library.responsive_images.use_tiny_placeholders', false); + config()->set('media-library.convert_gif_to_webp_using_gif2webp', true); + + $testModel = new class() extends TestModelWithoutMediaConversions + { + public function registerMediaCollections(): void + { + $this->addMediaCollection('images') + ->registerMediaConversions(function (Media $media) { + $this + ->addMediaConversion('webp') + ->withResponsiveImages() + ->greyscale() + ->format('webp'); + }); + } + }; + + $model = $testModel::create(['name' => 'testmodel']); + $model->addMedia($this->getTestGif()) + ->toMediaCollection('images'); + + $imagick = Image::useImageDriver(config('media-library.image_driver'))->loadFile($this->getTempDirectory("media/1/{$this->fileName}.gif"))->image(); + + expect(count($imagick))->toBe(10); + + $imagick = Image::useImageDriver(config('media-library.image_driver'))->loadFile($this->getTempDirectory("media/1/responsive-images/{$this->fileName}___webp_267_267.webp"))->image(); + + expect(count($imagick))->toBe(10); +})->with(['imagick']); diff --git a/tests/TestCase.php b/tests/TestCase.php index 13f4b1418..a2d6d1106 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -251,6 +251,11 @@ public function getTestMp4(): string return $this->getTestFilesDirectory('test.mp4'); } + public function getTestGif(): string + { + return $this->getTestFilesDirectory('test.gif'); + } + public function getTestImageWithoutExtension(): string { return $this->getTestFilesDirectory('image'); diff --git a/tests/TestSupport/testfiles/test.gif b/tests/TestSupport/testfiles/test.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a180fe8631100b8b9b121e1c76f7a11f7a4f338 GIT binary patch literal 109693 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 literal 0 HcmV?d00001 From a92cbc3337261153bc17584472db6c464763e5d3 Mon Sep 17 00:00:00 2001 From: jhorie Date: Thu, 1 Feb 2024 08:47:35 +0100 Subject: [PATCH 12/18] Lossy added --- composer.json | 9 ++++++++- src/Conversions/Actions/PerformConversionAction.php | 2 +- src/ResponsiveImages/ResponsiveImageGenerator.php | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c497a7300..3643b5dea 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "illuminate/pipeline": "^10.0", "illuminate/support": "^10.0", "maennchen/zipstream-php": "^3.1", - "spatie/image": "^3.3.2", + "spatie/image": "dev-manipulating_animated_gifs", "spatie/laravel-package-tools": "^1.16.1", "spatie/temporary-directory": "^2.2", "symfony/console": "^6.4.1|^7.0" @@ -55,6 +55,13 @@ "spatie/pdf-to-image": "^2.2", "spatie/pest-plugin-snapshots": "^2.1" }, + "repositories": [ + { + "type": "vcs", + "name": "spatie/image", + "url": "git@github.com:jhorie/image.git" + } + ], "conflict": { "php-ffmpeg/php-ffmpeg": "<0.6.1" }, diff --git a/src/Conversions/Actions/PerformConversionAction.php b/src/Conversions/Actions/PerformConversionAction.php index 20c314d04..ffd463465 100644 --- a/src/Conversions/Actions/PerformConversionAction.php +++ b/src/Conversions/Actions/PerformConversionAction.php @@ -46,7 +46,7 @@ public function execute( if ($shouldUseGif2WebpConverter) { $manipulatedFile = pathinfo($renamedFile, PATHINFO_DIRNAME) . '/' . (Str::random(32) . '.' . $media->extension); copy($renamedFile, $manipulatedFile); - exec("gif2webp " . $renamedFile . " -o " . $renamedFile); + exec("gif2webp -lossy " . $renamedFile . " -o " . $renamedFile); } if ($conversion->shouldGenerateResponsiveImages()) { diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index 0321a2b0a..17ec4fec9 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -110,7 +110,7 @@ public function generateResponsiveImage( rename($tempDestination, $responsiveImagePath); if ($shouldUseGif2WebpConverter) { - exec("gif2webp " . $responsiveImagePath . " -o " . $responsiveImagePath); + exec("gif2webp -lossy " . $responsiveImagePath . " -o " . $responsiveImagePath); } $this->filesystem->copyToMediaLibrary($responsiveImagePath, $media, 'responsiveImages'); From 53f594b25f579e823f2f869f74c20ca53e37ee28 Mon Sep 17 00:00:00 2001 From: jhorie Date: Thu, 1 Feb 2024 11:25:57 +0100 Subject: [PATCH 13/18] Video fix --- src/Conversions/Actions/PerformManipulationsAction.php | 2 +- src/Conversions/ImageGenerators/Video.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Conversions/Actions/PerformManipulationsAction.php b/src/Conversions/Actions/PerformManipulationsAction.php index 4aba2201d..a7a91deee 100644 --- a/src/Conversions/Actions/PerformManipulationsAction.php +++ b/src/Conversions/Actions/PerformManipulationsAction.php @@ -30,7 +30,7 @@ public function execute( $conversion->format($media->extension); } - if (Str::startsWith(File::mimeType($conversionTempFile), "video/") && $conversion->getManipulations()->getManipulationArgument('format') == "webm") { + if (Str::startsWith(File::mimeType($conversionTempFile), "video/") && $conversion->getManipulations()->getManipulationArgument('format') == ["webm"]) { exec("ffmpeg -i " . $conversionTempFile . " -f webm -an " . $conversionTempFile . ".webm"); if (File::exists($conversionTempFile . '.webm')) { unlink($conversionTempFile); diff --git a/src/Conversions/ImageGenerators/Video.php b/src/Conversions/ImageGenerators/Video.php index 762505848..f0a553741 100644 --- a/src/Conversions/ImageGenerators/Video.php +++ b/src/Conversions/ImageGenerators/Video.php @@ -12,7 +12,7 @@ class Video extends ImageGenerator { public function convert(string $file, ?Conversion $conversion = null): ?string { - if ($conversion->getManipulations()->getManipulationArgument('format') == "webm") { + if ($conversion->getManipulations()->getManipulationArgument('format') == ["webm"]) { return $file; } From 98568dd289bfc503e59259687c9201d24b4786fc Mon Sep 17 00:00:00 2001 From: jhorie Date: Tue, 13 Feb 2024 15:44:31 +0100 Subject: [PATCH 14/18] Timeout increased --- src/Conversions/Conversion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index a83ad3bd6..03b620819 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -39,7 +39,7 @@ class Conversion public function __construct( protected string $name, ) { - $optimizerChain = OptimizerChainFactory::create(config('media-library.image_optimizers')); + $optimizerChain = OptimizerChainFactory::create(config('media-library.image_optimizers'))->setTimeout(config('media-library.image_optimizer_timeout') ?? 60); $this->manipulations = new Manipulations(); $this->manipulations->optimize($optimizerChain)->format('jpg'); From f7d91fd0632a7652beadc404854a854df9f5ef96 Mon Sep 17 00:00:00 2001 From: jhorie Date: Wed, 18 Dec 2024 17:40:32 +0100 Subject: [PATCH 15/18] Added feature withoutTouchingFiles --- .../Actions/PerformConversionAction.php | 10 ++++++++-- src/Conversions/Conversion.php | 13 +++++++++++++ .../ResponsiveImageGenerator.php | 19 ++++++++++++------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/Conversions/Actions/PerformConversionAction.php b/src/Conversions/Actions/PerformConversionAction.php index ffd463465..c7f3a46c9 100644 --- a/src/Conversions/Actions/PerformConversionAction.php +++ b/src/Conversions/Actions/PerformConversionAction.php @@ -20,7 +20,9 @@ public function execute( ) { $imageGenerator = ImageGeneratorFactory::forMedia($media); - $copiedOriginalFile = $imageGenerator->convert($copiedOriginalFile, $conversion); + if ($conversion->shouldTouchFiles()) { + $copiedOriginalFile = $imageGenerator->convert($copiedOriginalFile, $conversion); + } if (! $copiedOriginalFile) { return; @@ -36,7 +38,11 @@ public function execute( event(new ConversionWillStartEvent($media, $conversion, $copiedOriginalFile)); - $manipulationResult = (new PerformManipulationsAction())->execute($media, $conversion, $copiedOriginalFile); + if (!$conversion->shouldTouchFiles()) { + $manipulationResult = (new PerformManipulationsAction())->execute($media, $conversion, $copiedOriginalFile); + } else { + $manipulationResult = $copiedOriginalFile; + } $newFileName = $conversion->getConversionFile($media); diff --git a/src/Conversions/Conversion.php b/src/Conversions/Conversion.php index 03b620819..74b78ab36 100644 --- a/src/Conversions/Conversion.php +++ b/src/Conversions/Conversion.php @@ -30,6 +30,8 @@ class Conversion protected ?WidthCalculator $widthCalculator = null; + protected bool $withoutTouchingFiles = false; + protected ?string $loadingAttributeValue; protected int $pdfPageNumber = 1; @@ -218,6 +220,17 @@ public function getWidthCalculator(): ?WidthCalculator return $this->widthCalculator; } + public function withoutTouchingFiles(): self + { + $this->withoutTouchingFiles = true; + + return $this; + } + + public function shouldTouchFiles(): bool { + return !$this->withoutTouchingFiles; + } + public function shouldGenerateResponsiveImages(): bool { return $this->generateResponsiveImages; diff --git a/src/ResponsiveImages/ResponsiveImageGenerator.php b/src/ResponsiveImages/ResponsiveImageGenerator.php index 17ec4fec9..5f2d2849f 100644 --- a/src/ResponsiveImages/ResponsiveImageGenerator.php +++ b/src/ResponsiveImages/ResponsiveImageGenerator.php @@ -61,7 +61,7 @@ public function generateResponsiveImagesForConversion(Media $media, Conversion $ $widthCalculator = $conversion->getWidthCalculator() ?? $this->widthCalculator; foreach ($widthCalculator->calculateWidthsFromFile($baseImage) as $width) { - $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion), $shouldUseGif2WebpConverter); + $this->generateResponsiveImage($media, $baseImage, $conversion->getName(), $width, $temporaryDirectory, $this->getConversionQuality($conversion), $shouldUseGif2WebpConverter, $conversion->shouldTouchFiles()); } $this->generateTinyJpg($media, $baseImage, $conversion->getName(), $temporaryDirectory); @@ -81,18 +81,23 @@ public function generateResponsiveImage( int $targetWidth, BaseTemporaryDirectory $temporaryDirectory, int $conversionQuality = self::DEFAULT_CONVERSION_QUALITY, - bool $shouldUseGif2WebpConverter = false + bool $shouldUseGif2WebpConverter = false, + bool $shouldTouchFiles = true ): void { $extension = $this->fileNamer->extensionFromBaseImage($baseImage); $responsiveImagePath = $this->fileNamer->temporaryFileName($media, $extension); $tempDestination = $temporaryDirectory->path($responsiveImagePath); - ImageFactory::load($baseImage) - ->optimize() - ->width($targetWidth) - ->quality($conversionQuality) - ->save($tempDestination); + if ($shouldTouchFiles) { + ImageFactory::load($baseImage) + ->optimize() + ->width($targetWidth) + ->quality($conversionQuality) + ->save($tempDestination); + } else { + copy($baseImage, $tempDestination); + } $responsiveImageHeight = ImageFactory::load($tempDestination)->getHeight(); From 6e7fa7412504b5092fae9c8e555354bce29a467d Mon Sep 17 00:00:00 2001 From: jhorie Date: Wed, 18 Dec 2024 17:48:26 +0100 Subject: [PATCH 16/18] Added feature withoutTouchingFiles --- src/Conversions/Actions/PerformConversionAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Conversions/Actions/PerformConversionAction.php b/src/Conversions/Actions/PerformConversionAction.php index c7f3a46c9..612c4589f 100644 --- a/src/Conversions/Actions/PerformConversionAction.php +++ b/src/Conversions/Actions/PerformConversionAction.php @@ -38,7 +38,7 @@ public function execute( event(new ConversionWillStartEvent($media, $conversion, $copiedOriginalFile)); - if (!$conversion->shouldTouchFiles()) { + if ($conversion->shouldTouchFiles()) { $manipulationResult = (new PerformManipulationsAction())->execute($media, $conversion, $copiedOriginalFile); } else { $manipulationResult = $copiedOriginalFile; From c6effc7c02acdb3784220bb96ffaa93ba1c863fc Mon Sep 17 00:00:00 2001 From: askjdakjshdkjasdh Date: Fri, 13 Jun 2025 14:46:04 +0200 Subject: [PATCH 17/18] Remove unused custom repository definition from composer.json --- composer.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/composer.json b/composer.json index 3643b5dea..09a4c9a56 100644 --- a/composer.json +++ b/composer.json @@ -55,13 +55,6 @@ "spatie/pdf-to-image": "^2.2", "spatie/pest-plugin-snapshots": "^2.1" }, - "repositories": [ - { - "type": "vcs", - "name": "spatie/image", - "url": "git@github.com:jhorie/image.git" - } - ], "conflict": { "php-ffmpeg/php-ffmpeg": "<0.6.1" }, From 7e3294c3b36d4b1b396e838e058d68f1a958f2b2 Mon Sep 17 00:00:00 2001 From: askjdakjshdkjasdh Date: Fri, 13 Jun 2025 14:50:35 +0200 Subject: [PATCH 18/18] Update spatie/image dependency to stable version ^3.3.2 in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 17fa6204f..e85f5dcbd 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "illuminate/pipeline": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0", "maennchen/zipstream-php": "^3.1", - "spatie/image": "dev-manipulating_animated_gifs", + "spatie/image": "^3.3.2", "spatie/laravel-package-tools": "^1.16.1", "spatie/temporary-directory": "^2.2", "symfony/console": "^6.4.1|^7.0"