diff --git a/src/Services/ImageConverter.php b/src/Services/ImageConverter.php index b7659434..af947057 100644 --- a/src/Services/ImageConverter.php +++ b/src/Services/ImageConverter.php @@ -18,7 +18,6 @@ class ImageConverter $this->imageManipulator = $imageManipulator; } - public function createImageFromBuffer($source) { $tmpSourcePath = tempnam(sys_get_temp_dir(), 'thumb') . '.dat'; diff --git a/src/Services/ImageManipulation/GdImageManipulator.php b/src/Services/ImageManipulation/GdImageManipulator.php index 276355b1..9f8aa58d 100644 --- a/src/Services/ImageManipulation/GdImageManipulator.php +++ b/src/Services/ImageManipulation/GdImageManipulator.php @@ -81,6 +81,7 @@ class GdImageManipulator implements IImageManipulator break; default: + throw new \InvalidArgumentException('Not supported'); } $buffer = ob_get_contents(); diff --git a/src/Services/ThumbnailGenerator.php b/src/Services/ThumbnailGenerator.php index 4e576d4f..f948a11e 100644 --- a/src/Services/ThumbnailGenerator.php +++ b/src/Services/ThumbnailGenerator.php @@ -1,6 +1,5 @@ imageConverter = $imageConverter; } - public function generate($source, $width, $height, $cropStyle) + public function generate($source, $width, $height, $cropStyle, $format) { $image = $this->imageConverter->createImageFromBuffer($source); if (!$image) @@ -40,9 +39,7 @@ class ThumbnailGenerator throw new \InvalidArgumentException('Unknown thumbnail crop style'); } - return $this->imageManipulator->saveToBuffer( - $image, - IImageManipulator::FORMAT_JPEG); + return $this->imageManipulator->saveToBuffer($image, $format); } private function cropOutside(&$image, $srcWidth, $srcHeight, $dstWidth, $dstHeight) diff --git a/src/Services/ThumbnailService.php b/src/Services/ThumbnailService.php index d9b3d7ba..f0508576 100644 --- a/src/Services/ThumbnailService.php +++ b/src/Services/ThumbnailService.php @@ -2,10 +2,15 @@ namespace Szurubooru\Services; use Szurubooru\Config; use Szurubooru\Dao\PublicFileDao; +use Szurubooru\Helpers\ProgramExecutor; +use Szurubooru\Services\ImageManipulation\IImageManipulator; use Szurubooru\Services\ThumbnailGenerator; class ThumbnailService { + const PROGRAM_NAME_JPEGOPTIM = 'jpegoptim'; + const PROGRAM_NAME_OPTIPNG = 'optipng'; + private $config; private $fileDao; private $thumbnailGenerator; @@ -59,11 +64,13 @@ class ThumbnailService $source = $this->fileDao->load($sourceName); if ($source) { - $thumbnailContent = $this->thumbnailGenerator->generate($source, $width, $height, $cropStyle); + $format = $this->getFormat(); + $thumbnailContent = $this->thumbnailGenerator->generate($source, $width, $height, $cropStyle, $format); if ($thumbnailContent) { $targetName = $this->getTargetName($sourceName, $width, $height); $this->fileDao->save($targetName, $thumbnailContent); + $this->optimize($targetName, $format); return $targetName; } } @@ -97,4 +104,35 @@ class ThumbnailService { return 'thumbnails' . DIRECTORY_SEPARATOR . 'blank.png'; } + + private function getFormat() + { + return IImageManipulator::FORMAT_JPEG; + } + + private function optimize($sourceName, $format) + { + $sourcePath = $this->fileDao->getFullPath($sourceName); + + if ($format === IImageManipulator::FORMAT_JPEG and ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_JPEGOPTIM)) + { + ProgramExecutor::run( + self::PROGRAM_NAME_JPEGOPTIM, + [ + '--quiet', + '--strip-all', + $sourcePath, + ]); + } + + elseif ($format === IImageManipulator::FORMAT_PNG and ProgramExecutor::isProgramAvailable(self::PROGRAM_NAME_OPTIPNG)) + { + ProgramExecutor::run( + self::PROGRAM_NAME_OPTIPNG, + [ + '-o2', + $sourcePath, + ]); + } + } } diff --git a/tests/Services/ThumbnailGeneratorTest.php b/tests/Services/ThumbnailGeneratorTest.php index 3dc4abb7..1ec32cf5 100644 --- a/tests/Services/ThumbnailGeneratorTest.php +++ b/tests/Services/ThumbnailGeneratorTest.php @@ -3,6 +3,7 @@ namespace Szurubooru\Tests\Services; use Szurubooru\Helpers\ProgramExecutor; use Szurubooru\Injector; use Szurubooru\Services\ImageConverter; +use Szurubooru\Services\ImageManipulation\IImageManipulator; use Szurubooru\Services\ImageManipulation\ImageManipulator; use Szurubooru\Services\ThumbnailGenerator; use Szurubooru\Tests\AbstractTestCase; @@ -24,7 +25,8 @@ final class ThumbnailGeneratorTest extends AbstractTestCase $this->getTestFile('flash.swf'), 150, 150, - ThumbnailGenerator::CROP_OUTSIDE); + ThumbnailGenerator::CROP_OUTSIDE, + IImageManipulator::FORMAT_PNG); $image = $imageManipulator->loadFromBuffer($result); $this->assertEquals(150, $imageManipulator->getImageWidth($image)); @@ -46,7 +48,8 @@ final class ThumbnailGeneratorTest extends AbstractTestCase $this->getTestFile('video.mp4'), 150, 150, - ThumbnailGenerator::CROP_OUTSIDE); + ThumbnailGenerator::CROP_OUTSIDE, + IImageManipulator::FORMAT_PNG); $image = $imageManipulator->loadFromBuffer($result); $this->assertEquals(150, $imageManipulator->getImageWidth($image)); @@ -62,7 +65,8 @@ final class ThumbnailGeneratorTest extends AbstractTestCase $this->getTestFile('image.jpg'), 150, 150, - ThumbnailGenerator::CROP_OUTSIDE); + ThumbnailGenerator::CROP_OUTSIDE, + IImageManipulator::FORMAT_PNG); $image = $imageManipulator->loadFromBuffer($result); $this->assertEquals(150, $imageManipulator->getImageWidth($image)); @@ -72,7 +76,8 @@ final class ThumbnailGeneratorTest extends AbstractTestCase $this->getTestFile('image.jpg'), 150, 150, - ThumbnailGenerator::CROP_INSIDE); + ThumbnailGenerator::CROP_INSIDE, + IImageManipulator::FORMAT_PNG); $image = $imageManipulator->loadFromBuffer($result); $this->assertEquals(150, $imageManipulator->getImageWidth($image)); @@ -89,7 +94,8 @@ final class ThumbnailGeneratorTest extends AbstractTestCase $this->getTestFile('text.txt'), 150, 150, - ThumbnailGenerator::CROP_OUTSIDE); + ThumbnailGenerator::CROP_OUTSIDE, + IImageManipulator::FORMAT_PNG); } public function getImageManipulator()