From 071bc4217d00e580594c6d8ed2c353f2f09e07c2 Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 21 Jul 2024 18:04:45 +0200 Subject: [PATCH] :octocat: add mime type guesser to QROutputAbstract (#223) --- composer.json | 1 + examples/imagickWithLogo.php | 2 +- src/Output/QRImagick.php | 21 ++---------------- src/Output/QROutputAbstract.php | 38 ++++++++++++++++++++++++++++++--- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index c49d95bcf..f955096ff 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "chillerlan/php-settings-container": "^3.2.1" }, "require-dev": { + "ext-fileinfo": "*", "chillerlan/php-authenticator": "^5.2.1", "intervention/image": "^3.7", "phpbench/phpbench": "^1.2.15", diff --git a/examples/imagickWithLogo.php b/examples/imagickWithLogo.php index d6c19400a..de6bed1eb 100644 --- a/examples/imagickWithLogo.php +++ b/examples/imagickWithLogo.php @@ -56,7 +56,7 @@ public function dump(string|null $file = null):string{ $this->saveToFile($imageData, $file); if($this->options->outputBase64){ - $imageData = $this->toBase64DataURI($imageData, $this->guessMimeType($imageData)); + $imageData = $this->toBase64DataURI($imageData); } return $imageData; diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index 90396f2e9..47f0f0e55 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -16,9 +16,8 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\Settings\SettingsContainerInterface; -use finfo, Imagick, ImagickDraw, ImagickPixel; +use Imagick, ImagickDraw, ImagickPixel; use function extension_loaded, in_array, is_string, max, min, preg_match, sprintf, strlen; -use const FILEINFO_MIME_TYPE; /** * ImageMagick output module (requires ext-imagick) @@ -123,28 +122,12 @@ public function dump(string|null $file = null):string|Imagick{ $this->saveToFile($imageData, $file); if($this->options->outputBase64){ - - $imageData = $this->toBase64DataURI($imageData, $this->guessMimeType($imageData)); + $imageData = $this->toBase64DataURI($imageData); } return $imageData; } - /** - * @todo: move to QROutputAbstract - * - * @throws \chillerlan\QRCode\Output\QRCodeOutputException - */ - protected function guessMimeType(string $imageData):string{ - $mime = (new finfo(FILEINFO_MIME_TYPE))->buffer($imageData); - - if($mime === false){ - throw new QRCodeOutputException('unable to detect mime type'); - } - - return $mime; - } - /** * Sets the background color */ diff --git a/src/Output/QROutputAbstract.php b/src/Output/QROutputAbstract.php index ab97e3b72..ece420c79 100644 --- a/src/Output/QROutputAbstract.php +++ b/src/Output/QROutputAbstract.php @@ -6,6 +6,8 @@ * @author Smiley * @copyright 2015 Smiley * @license MIT + * + * @noinspection PhpComposerExtensionStubsInspection */ declare(strict_types=1); @@ -14,8 +16,9 @@ use chillerlan\QRCode\QROptions; use chillerlan\QRCode\Data\QRMatrix; use chillerlan\Settings\SettingsContainerInterface; -use Closure; -use function base64_encode, dirname, file_put_contents, is_writable, ksort, sprintf; +use Closure, finfo; +use function base64_encode, dirname, extension_loaded, file_put_contents, is_writable, ksort, sprintf; +use const FILEINFO_MIME_TYPE; /** * common output abstract @@ -191,9 +194,38 @@ protected function getModuleValueAt(int $x, int $y):mixed{ /** * Returns a base64 data URI for the given string and mime type + * + * The mime type can be set via class constant MIME_TYPE in child classes, + * or given via $mime, otherwise it is guessed from the image $data. */ protected function toBase64DataURI(string $data, string|null $mime = null):string{ - return sprintf('data:%s;base64,%s', ($mime ?? static::MIME_TYPE), base64_encode($data)); + $mime ??= static::MIME_TYPE; + + if($mime === ''){ + $mime = $this->guessMimeType($data); + } + + return sprintf('data:%s;base64,%s', $mime, base64_encode($data)); + } + + /** + * Guesses the mime type from the given $imageData + * + * @throws \chillerlan\QRCode\Output\QRCodeOutputException + */ + protected function guessMimeType(string $imageData):string{ + + if(!extension_loaded('fileinfo')){ + throw new QRCodeOutputException('ext-fileinfo not loaded, cannot guess mime type'); + } + + $mime = (new finfo(FILEINFO_MIME_TYPE))->buffer($imageData); + + if($mime === false){ + throw new QRCodeOutputException('unable to detect mime type'); + } + + return $mime; } /**