mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-10-26 21:56:24 +00:00
:octocat: QRGdImage: add BMP and WEBP support, deprecate QROptionsTrait::$jpegQuality and QROptionsTrait::$pngCompression in favor of QROptionsTrait::$quality
This commit is contained in:
+61
-17
@@ -14,10 +14,12 @@ namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
use ErrorException, Throwable;
|
||||
use function array_values, count, extension_loaded, imagecolorallocate, imagecolortransparent, imagecreatetruecolor,
|
||||
imagedestroy, imagefilledellipse, imagefilledrectangle, imagegif, imagejpeg, imagepng, imagescale, intdiv, intval,
|
||||
is_array, is_numeric, max, min, ob_end_clean, ob_get_contents, ob_start, restore_error_handler, set_error_handler;
|
||||
use ErrorException;
|
||||
use Throwable;
|
||||
use function array_values, count, extension_loaded, gd_info, imagebmp, imagecolorallocate, imagecolortransparent,
|
||||
imagecreatetruecolor, imagedestroy, imagefilledellipse, imagefilledrectangle, imagegif, imagejpeg, imagepng,
|
||||
imagescale, imagewebp, intdiv, intval, is_array, is_numeric, max, min, ob_end_clean, ob_get_contents, ob_start,
|
||||
restore_error_handler, set_error_handler, sprintf;
|
||||
|
||||
/**
|
||||
* Converts the matrix into GD images, raw or base64 output (requires ext-gd)
|
||||
@@ -55,18 +57,56 @@ class QRGdImage extends QROutputAbstract{
|
||||
* @noinspection PhpMissingParentConstructorInspection
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
|
||||
|
||||
if(!extension_loaded('gd')){
|
||||
throw new QRCodeOutputException('ext-gd not loaded'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$this->options = $options;
|
||||
$this->matrix = $matrix;
|
||||
|
||||
$this->checkGD();
|
||||
$this->setMatrixDimensions();
|
||||
|
||||
// we're scaling the image up in order to draw crisp round circles, otherwise they appear square-y on small scales
|
||||
// @see https://github.com/chillerlan/php-qrcode/issues/23
|
||||
$this->image = $this->createImage();
|
||||
// set module values after image creation because we need the GdImage instance
|
||||
$this->setModuleValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether GD is installed and if the given mode is supported
|
||||
*
|
||||
* @return void
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function checkGD():void{
|
||||
|
||||
if(!extension_loaded('gd')){
|
||||
throw new QRCodeOutputException('ext-gd not loaded');
|
||||
}
|
||||
|
||||
$info = gd_info();
|
||||
$mode = [
|
||||
self::GDIMAGE_BMP => 'BMP Support',
|
||||
self::GDIMAGE_GIF => 'GIF Create Support',
|
||||
self::GDIMAGE_JPG => 'JPEG Support',
|
||||
self::GDIMAGE_PNG => 'PNG Support',
|
||||
self::GDIMAGE_WEBP => 'WebP Support',
|
||||
][$this->options->outputType];
|
||||
|
||||
if(!isset($info[$mode]) || $info[$mode] !== true){
|
||||
throw new QRCodeOutputException(sprintf('output mode "%s" not supported', $this->options->outputType));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GdImage resource and scales it if necessary
|
||||
*
|
||||
* we're scaling the image up in order to draw crisp round circles, otherwise they appear square-y on small scales
|
||||
*
|
||||
* @see https://github.com/chillerlan/php-qrcode/issues/23
|
||||
*
|
||||
* @return \GdImage|resource
|
||||
*/
|
||||
protected function createImage(){
|
||||
|
||||
if($this->options->drawCircularModules && $this->options->scale < 20){
|
||||
// increase the initial image size by 10
|
||||
$this->length = (($this->length + 2) * 10);
|
||||
@@ -74,9 +114,7 @@ class QRGdImage extends QROutputAbstract{
|
||||
$this->upscaled = true;
|
||||
}
|
||||
|
||||
$this->image = imagecreatetruecolor($this->length, $this->length);
|
||||
// set module values after image creation because we need the GdImage instance
|
||||
$this->setModuleValues();
|
||||
return imagecreatetruecolor($this->length, $this->length);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +263,7 @@ class QRGdImage extends QROutputAbstract{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the QR image
|
||||
* Draws the QR image
|
||||
*/
|
||||
protected function drawImage():void{
|
||||
foreach($this->matrix->getMatrix() as $y => $row){
|
||||
@@ -282,16 +320,22 @@ class QRGdImage extends QROutputAbstract{
|
||||
try{
|
||||
|
||||
switch($this->options->outputType){
|
||||
case QROutputInterface::GDIMAGE_BMP:
|
||||
imagebmp($this->image);
|
||||
break;
|
||||
case QROutputInterface::GDIMAGE_GIF:
|
||||
imagegif($this->image);
|
||||
break;
|
||||
case QROutputInterface::GDIMAGE_JPG:
|
||||
imagejpeg($this->image, null, max(0, min(100, $this->options->jpegQuality)));
|
||||
imagejpeg($this->image, null, max(-1, min(100, $this->options->quality)));
|
||||
break;
|
||||
case QROutputInterface::GDIMAGE_WEBP:
|
||||
imagewebp($this->image, null, max(-1, min(100, $this->options->quality)));
|
||||
break;
|
||||
// silently default to png output
|
||||
case QROutputInterface::GDIMAGE_PNG:
|
||||
default:
|
||||
imagepng($this->image, null, max(-1, min(9, $this->options->pngCompression)));
|
||||
imagepng($this->image, null, max(-1, min(9, $this->options->quality)));
|
||||
}
|
||||
|
||||
$imageData = ob_get_contents();
|
||||
|
||||
@@ -18,27 +18,31 @@ use chillerlan\QRCode\Data\QRMatrix;
|
||||
interface QROutputInterface{
|
||||
|
||||
/** @var string */
|
||||
public const MARKUP_HTML = 'html';
|
||||
public const MARKUP_HTML = 'html';
|
||||
/** @var string */
|
||||
public const MARKUP_SVG = 'svg';
|
||||
public const MARKUP_SVG = 'svg';
|
||||
/** @var string */
|
||||
public const GDIMAGE_PNG = 'png';
|
||||
public const GDIMAGE_BMP = 'bmp';
|
||||
/** @var string */
|
||||
public const GDIMAGE_JPG = 'jpg';
|
||||
public const GDIMAGE_GIF = 'gif';
|
||||
/** @var string */
|
||||
public const GDIMAGE_GIF = 'gif';
|
||||
public const GDIMAGE_JPG = 'jpg';
|
||||
/** @var string */
|
||||
public const STRING_JSON = 'json';
|
||||
public const GDIMAGE_PNG = 'png';
|
||||
/** @var string */
|
||||
public const STRING_TEXT = 'text';
|
||||
public const GDIMAGE_WEBP = 'webp';
|
||||
/** @var string */
|
||||
public const IMAGICK = 'imagick';
|
||||
public const STRING_JSON = 'json';
|
||||
/** @var string */
|
||||
public const FPDF = 'fpdf';
|
||||
public const STRING_TEXT = 'text';
|
||||
/** @var string */
|
||||
public const EPS = 'eps';
|
||||
public const IMAGICK = 'imagick';
|
||||
/** @var string */
|
||||
public const CUSTOM = 'custom';
|
||||
public const FPDF = 'fpdf';
|
||||
/** @var string */
|
||||
public const EPS = 'eps';
|
||||
/** @var string */
|
||||
public const CUSTOM = 'custom';
|
||||
|
||||
/**
|
||||
* Map of built-in output modes => class FQN
|
||||
@@ -46,16 +50,18 @@ interface QROutputInterface{
|
||||
* @var string[]
|
||||
*/
|
||||
public const MODES = [
|
||||
self::MARKUP_SVG => QRMarkupSVG::class,
|
||||
self::MARKUP_HTML => QRMarkupHTML::class,
|
||||
self::GDIMAGE_PNG => QRGdImage::class,
|
||||
self::GDIMAGE_GIF => QRGdImage::class,
|
||||
self::GDIMAGE_JPG => QRGdImage::class,
|
||||
self::STRING_JSON => QRString::class,
|
||||
self::STRING_TEXT => QRString::class,
|
||||
self::IMAGICK => QRImagick::class,
|
||||
self::FPDF => QRFpdf::class,
|
||||
self::EPS => QREps::class,
|
||||
self::MARKUP_SVG => QRMarkupSVG::class,
|
||||
self::MARKUP_HTML => QRMarkupHTML::class,
|
||||
self::GDIMAGE_BMP => QRGdImage::class,
|
||||
self::GDIMAGE_GIF => QRGdImage::class,
|
||||
self::GDIMAGE_JPG => QRGdImage::class,
|
||||
self::GDIMAGE_PNG => QRGdImage::class,
|
||||
self::GDIMAGE_WEBP => QRGdImage::class,
|
||||
self::STRING_JSON => QRString::class,
|
||||
self::STRING_TEXT => QRString::class,
|
||||
self::IMAGICK => QRImagick::class,
|
||||
self::FPDF => QRFpdf::class,
|
||||
self::EPS => QREps::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
+63
-3
@@ -89,7 +89,7 @@ trait QROptionsTrait{
|
||||
* The built-in output type
|
||||
*
|
||||
* - QROutputInterface::MARKUP_XXXX where XXXX = HTML, SVG
|
||||
* - QROutputInterface::GDIMAGE_XXX where XXX = PNG, GIF, JPG
|
||||
* - QROutputInterface::GDIMAGE_XXX where XXX = BMP, GIF, JPG, PNG, WEBP
|
||||
* - QROutputInterface::STRING_XXXX where XXXX = TEXT, JSON
|
||||
* - QROutputInterface::IMAGICK
|
||||
* - QROutputInterface::EPS
|
||||
@@ -268,18 +268,32 @@ trait QROptionsTrait{
|
||||
*/
|
||||
protected $transparencyColor = null;
|
||||
|
||||
/**
|
||||
* Compression quality
|
||||
*
|
||||
* The given value depends on the used output type:
|
||||
*
|
||||
* @see \imagejpeg()
|
||||
* @see \imagepng()
|
||||
* @see \imagewebp()
|
||||
* @see \Imagick::setImageCompressionQuality()
|
||||
*/
|
||||
protected int $quality = -1;
|
||||
|
||||
|
||||
/*
|
||||
* QRGdImage settings
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see imagepng()
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
*/
|
||||
protected int $pngCompression = -1;
|
||||
|
||||
/**
|
||||
* @see imagejpeg()
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
*/
|
||||
protected int $jpegQuality = 85;
|
||||
|
||||
@@ -541,6 +555,7 @@ trait QROptionsTrait{
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$outputBase64 instead
|
||||
* @see \chillerlan\QRCode\QROptions::$outputBase64
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function set_imageBase64(bool $imageBase64):void{
|
||||
$this->outputBase64 = $imageBase64;
|
||||
@@ -551,9 +566,54 @@ trait QROptionsTrait{
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$outputBase64 instead
|
||||
* @see \chillerlan\QRCode\QROptions::$outputBase64
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function get_imageBase64():bool{
|
||||
return $this->outputBase64;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect call to the new variable
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function set_jpegQuality(bool $jpegQuality):void{
|
||||
$this->quality = $jpegQuality;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect call to the new variable
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function get_jpegQuality():bool{
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect call to the new variable
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function set_pngCompression(bool $pngCompression):void{
|
||||
$this->quality = $pngCompression;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect call to the new variable
|
||||
*
|
||||
* @deprecated 5.0.0 use QROptions::$quality instead
|
||||
* @see \chillerlan\QRCode\QROptions::$quality
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function get_pngCompression():bool{
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRGdImageBMPTest
|
||||
*
|
||||
* @created 05.09.2023
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2023 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeTest\Output;
|
||||
|
||||
use chillerlan\QRCode\Output\QROutputInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class QRGdImageBMPTest extends QRGdImageTestAbstract{
|
||||
|
||||
protected string $type = QROutputInterface::GDIMAGE_BMP;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRGdImageWEBPTest
|
||||
*
|
||||
* @created 05.09.2023
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2023 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeTest\Output;
|
||||
|
||||
use chillerlan\QRCode\Output\QROutputInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class QRGdImageWEBPTest extends QRGdImageTestAbstract{
|
||||
|
||||
protected string $type = QROutputInterface::GDIMAGE_WEBP;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user