From 0457bd9cffccacf2f7dae38fe583fa9414afa86a Mon Sep 17 00:00:00 2001 From: philipp lang Date: Thu, 16 Sep 2021 01:11:00 +0200 Subject: [PATCH] Fixed: Resize png images and keep transparency --- classes/ImageResizer.php | 29 ++++++++++++++++++++++++----- compressors/Factory.php | 3 +-- lib/MediaPath.php | 5 +++++ tests/ResizerTest.php | 29 +++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/classes/ImageResizer.php b/classes/ImageResizer.php index 15d3d6b..3fbc3e6 100644 --- a/classes/ImageResizer.php +++ b/classes/ImageResizer.php @@ -58,13 +58,24 @@ class ImageResizer $ratios = collect(); $ratios->push($this->dimensions()); $ratios = $ratios->merge($this->sizes()); + [$origWidth, $origHeight] = getimagesize($this->file->root()); foreach (collect(Setting::get('breakpoints'))->push($this->dimensions()->get('width'))->unique() as $size) { foreach ($ratios as $ratio) { + $width = $size; $height = $size * $ratio->get('height') / $ratio->get('width'); + if ($height > $origHeight) { + $width = $width * $origHeight / $height; + $height = $origHeight; + } + + if (ceil($width) > $origWidth || ceil($height) > $origHeight) { + continue; + } + $return->push(collect([ - 'width' => round($size), + 'width' => round($width), 'height' => round($height), ])); } @@ -76,11 +87,19 @@ class ImageResizer private function generateVersions(): void { foreach ($this->possibleSizes() as $size) { - $temp = microtime().'.jpg'; + $temp = microtime().'.'.$this->file->extension(); + + $r = app(ImageManager::class)->make($this->file->root()); + if ($this->file->type() === 'image/jpeg') { + $r->fit($size->get('width'), $size->get('height'), fn ($constraint) => $constraint->upsize()) + ->save($this->disk->path($temp)); + } + if ($this->file->type() === 'image/png') { + app(ImageManager::class) + ->canvas($size->get('width'), $size->get('width'))->insert($r, 'center') + ->save($this->disk->path($temp)); + } - $r = app(ImageManager::class)->make($this->file->root()) - ->fit($size->get('width'), $size->get('height'), fn ($constraint) => $constraint->upsize()) - ->save($this->disk->path($temp)); list($destWidth, $destHeight) = getimagesize($this->disk->path($temp)); $versionFilename = $this->file->versionsDirPath(). diff --git a/compressors/Factory.php b/compressors/Factory.php index 34c224e..6a1025f 100644 --- a/compressors/Factory.php +++ b/compressors/Factory.php @@ -21,8 +21,7 @@ class Factory public function resolve(MediaPath $path): Compressor { - $mime = mime_content_type($path->root()); - $compiler = $this->resolveType($mime); + $compiler = $this->resolveType($path->type()); if (is_null($compiler)) { return new $this->default($path); diff --git a/lib/MediaPath.php b/lib/MediaPath.php index db27046..63d97a7 100644 --- a/lib/MediaPath.php +++ b/lib/MediaPath.php @@ -44,6 +44,11 @@ class MediaPath return pathinfo($this->path, PATHINFO_FILENAME); } + public function type(): string + { + return mime_content_type($this->root()); + } + public function extension(): string { return pathinfo($this->path, PATHINFO_EXTENSION); diff --git a/tests/ResizerTest.php b/tests/ResizerTest.php index bc84eb2..3c78083 100644 --- a/tests/ResizerTest.php +++ b/tests/ResizerTest.php @@ -195,6 +195,35 @@ class ResizerTest extends TestCase Event::fire('media.file.upload', [null, '/pages/test.png', null]); $this->assertHasFile('pages/test-100x100.png'); + $this->assertFileCount(3, 'pages'); + } + + public function testDontUpsizeAJpgImage(): void + { + Setting::set('folders', [['folder' => '/pages']]); + Setting::set('sizes', []); + Setting::set('breakpoints', ['100', '600']); + + $media = MediaLibrary::instance(); + $media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get()); + Event::fire('media.file.upload', [null, '/pages/test.jpg', null]); + + $this->assertHasFile('pages/test-100x100.jpg'); + $this->assertFileCount(3, 'pages'); + } + + public function testDontUpsizeAPngImage(): void + { + Setting::set('folders', [['folder' => '/pages']]); + Setting::set('sizes', []); + Setting::set('breakpoints', ['100', '600']); + + $media = MediaLibrary::instance(); + $media->put('/pages/test.png', UploadedFile::fake()->image('test.png', 500, 500)->get()); + Event::fire('media.file.upload', [null, '/pages/test.png', null]); + + $this->assertHasFile('pages/test-100x100.png'); + $this->assertFileCount(3, 'pages'); } }