From 739579552d54d1b24a75415af805faba37b975fd Mon Sep 17 00:00:00 2001 From: smiley Date: Sun, 31 Jul 2022 04:19:19 +0200 Subject: [PATCH] :octocat: clarify several QROptions: $imageTransparent and $imageTransparencyBG, introduced $drawLightModules and $bgColor (see #122) --- examples/image.php | 1 + examples/imagick.php | 4 ++- examples/svg.php | 4 +-- examples/svgRandomColoredDots.php | 2 +- examples/svgRoundQuietzone.php | 2 +- examples/svgWithLogo.php | 2 +- src/Output/QRGdImage.php | 15 +++++++++--- src/Output/QRImagick.php | 19 +++++++++------ src/Output/QRMarkupSVG.php | 2 +- src/QROptionsTrait.php | 35 ++++++++++++++++++--------- tests/Output/QRMarkupTestAbstract.php | 2 +- 11 files changed, 57 insertions(+), 31 deletions(-) diff --git a/examples/image.php b/examples/image.php index afa362ab3..c9375fcba 100644 --- a/examples/image.php +++ b/examples/image.php @@ -19,6 +19,7 @@ 'eccLevel' => EccLevel::L, 'scale' => 10, 'imageBase64' => false, + 'bgColor' => [200, 200, 200], 'imageTransparent' => false, 'drawCircularModules' => true, 'circleRadius' => 0.4, diff --git a/examples/imagick.php b/examples/imagick.php index 8ef8d6462..ba338a829 100644 --- a/examples/imagick.php +++ b/examples/imagick.php @@ -17,8 +17,10 @@ 'version' => 7, 'outputType' => QROutputInterface::IMAGICK, 'eccLevel' => EccLevel::L, - 'imagickBG' => '#FFFFFF', + 'bgColor' => '#cccccc', // overrides the imageTransparent setting + 'imageTransparent' => true, 'scale' => 20, + 'drawLightModules' => true, 'drawCircularModules' => true, 'circleRadius' => 0.4, 'keepAsSquare' => [QRMatrix::M_FINDER|QRMatrix::IS_DARK, QRMatrix::M_FINDER_DOT, QRMatrix::M_ALIGNMENT|QRMatrix::IS_DARK], diff --git a/examples/svg.php b/examples/svg.php index 05eda19c6..ae2c8c30c 100644 --- a/examples/svg.php +++ b/examples/svg.php @@ -22,8 +22,8 @@ 'imageBase64' => false, 'eccLevel' => EccLevel::L, 'addQuietzone' => true, - // if set to true, the light modules won't be rendered - 'imageTransparent' => false, + // if set to false, the light modules won't be rendered + 'drawLightModules' => true, // empty the default value to remove the fill* attributes from the elements 'markupDark' => '', 'markupLight' => '', diff --git a/examples/svgRandomColoredDots.php b/examples/svgRandomColoredDots.php index b18ca6b20..085e99cdf 100644 --- a/examples/svgRandomColoredDots.php +++ b/examples/svgRandomColoredDots.php @@ -124,7 +124,7 @@ class RandomDotsOptions extends QROptions{ 'outputInterface' => RandomDotsSVGOutput::class, 'markupDark' => '', 'markupLight' => '', - 'imageTransparent' => true, + 'drawLightModules' => false, 'connectPaths' => true, 'excludeFromConnect' => [ diff --git a/examples/svgRoundQuietzone.php b/examples/svgRoundQuietzone.php index f9a8ea4c3..ef8dd1a3f 100644 --- a/examples/svgRoundQuietzone.php +++ b/examples/svgRoundQuietzone.php @@ -174,7 +174,7 @@ class RoundQuietzoneOptions extends QROptions{ 'outputInterface' => RoundQuietzoneSVGoutput::class, // load our own output class 'markupDark' => '', // avoid "fill" attributes on paths 'markupLight' => '', - 'imageTransparent' => true, // set to false to add the light modules + 'drawLightModules' => false, // set to true to add the light modules 'connectPaths' => true, 'excludeFromConnect' => [ diff --git a/examples/svgWithLogo.php b/examples/svgWithLogo.php index 1a1b7f513..2546e3edc 100644 --- a/examples/svgWithLogo.php +++ b/examples/svgWithLogo.php @@ -109,7 +109,7 @@ protected function set_svgLogoScale(float $svgLogoScale):void{ 'eccLevel' => EccLevel::H, 'addQuietzone' => true, // if set to true, the light modules won't be rendered - 'imageTransparent' => false, + 'drawLightModules' => true, // empty the default value to remove the fill* attributes from the elements 'markupDark' => '', 'markupLight' => '', diff --git a/src/Output/QRGdImage.php b/src/Output/QRGdImage.php index 7449358e4..80fb3f9f6 100644 --- a/src/Output/QRGdImage.php +++ b/src/Output/QRGdImage.php @@ -95,14 +95,21 @@ public function dump(string $file = null){ $this->image = imagecreatetruecolor($this->length, $this->length); - // avoid: "Indirect modification of overloaded property $imageTransparencyBG has no effect" + // avoid: "Indirect modification of overloaded property $x has no effect" // https://stackoverflow.com/a/10455217 - $tbg = $this->options->imageTransparencyBG; + $bgColor = $this->options->imageTransparencyBG; + + if($this->moduleValueIsValid($this->options->bgColor)){ + $bgColor = $this->getModuleValue($this->options->bgColor); + } + /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ - $background = imagecolorallocate($this->image, ...$tbg); + $background = imagecolorallocate($this->image, ...$bgColor); if($this->options->imageTransparent && $this->options->outputType !== QROutputInterface::GDIMAGE_JPG){ - imagecolortransparent($this->image, $background); + $tbg = $this->options->imageTransparencyBG; + /** @phan-suppress-next-line PhanParamTooFewInternalUnpack */ + imagecolortransparent($this->image, imagecolorallocate($this->image, ...$tbg)); } imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $background); diff --git a/src/Output/QRImagick.php b/src/Output/QRImagick.php index 852439d88..7a6bf30c6 100644 --- a/src/Output/QRImagick.php +++ b/src/Output/QRImagick.php @@ -73,14 +73,14 @@ public function dump(string $file = null){ $file ??= $this->options->cachefile; $this->imagick = new Imagick; - $this->imagick->newImage( - $this->length, - $this->length, - new ImagickPixel($this->options->imagickBG ?? 'transparent'), - $this->options->imagickFormat - ); + $bgColor = $this->options->imageTransparent ? 'transparent' : 'white'; - $this->imagick->setImageType(Imagick::IMGTYPE_TRUECOLOR); + // keep the imagickBG property for now (until v6) + if($this->moduleValueIsValid($this->options->bgColor ?? $this->options->imagickBG)){ + $bgColor = $this->options->bgColor ?? $this->options->imagickBG; + } + + $this->imagick->newImage($this->length, $this->length, new ImagickPixel($bgColor), $this->options->imagickFormat); $this->drawImage(); @@ -119,6 +119,11 @@ protected function drawImage():void{ * draws a single pixel at the given position */ protected function setPixel(int $x, int $y, int $M_TYPE):void{ + + if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ + return; + } + $this->imagickDraw->setFillColor($this->moduleValues[$M_TYPE]); $this->options->drawCircularModules && $this->matrix->checkTypeNotIn($x, $y, $this->options->keepAsSquare) diff --git a/src/Output/QRMarkupSVG.php b/src/Output/QRMarkupSVG.php index b00f9ea69..e38421611 100644 --- a/src/Output/QRMarkupSVG.php +++ b/src/Output/QRMarkupSVG.php @@ -126,7 +126,7 @@ protected function getCssClass(int $M_TYPE):string{ */ protected function module(int $x, int $y, int $M_TYPE):string{ - if($this->options->imageTransparent && !$this->matrix->check($x, $y)){ + if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){ return ''; } diff --git a/src/QROptionsTrait.php b/src/QROptionsTrait.php index b95227095..cbe36a4c7 100644 --- a/src/QROptionsTrait.php +++ b/src/QROptionsTrait.php @@ -232,32 +232,41 @@ trait QROptionsTrait{ /** * toggle background transparency * - * - In GdImage mode (png, gif) it sets imagecolortransparent() with QROptions::$imageTransparencyBG. - * It also sets the "normal" background color without transparency switch. + * - GdImage: (png, gif) it sets imagecolortransparent() with {@see \chillerlan\QRCode\QROptions::$imageTransparencyBG} * - * - In SVG mode (as of v5), it won't render the "light" modules, - * as opacity/transparency can easily be set with css properties. * - * - It has no effect in the FPDF and Imagick output modules. - * - * @see \chillerlan\QRCode\QROptions::$imageTransparencyBG * @see https://github.com/chillerlan/php-qrcode/discussions/121 */ protected bool $imageTransparent = true; /** - * Sets the background color in GD mode. + * whether to draw the light (false) modules + * + * @var bool + */ + protected bool $drawLightModules = true; + + /** + * Sets the background color in GD mode: [R, G, B]. * - * When QROptions::$imageTransparent is set to true, this color is set as transparent in imagecolortransparent() + * When $imageTransparent is set to true, this color is set as transparent in imagecolortransparent() * * @see \chillerlan\QRCode\Output\QRGdImage * @see \chillerlan\QRCode\QROptions::$imageTransparent * @see imagecolortransparent() - * - * [R, G, B] */ protected array $imageTransparencyBG = [255, 255, 255]; + /** + * Sets the image background color (if applicable) + * + * - Imagick: defaults to "transparent" or "white", depending on $imageTransparent, {@see \ImagickPixel::__construct()} + * - GdImage: defaults to $imageTransparencyBG, {@see \chillerlan\QRCode\QROptions::$imageTransparencyBG} + * + * @var mixed|null + */ + protected $bgColor = null; + /** * @see imagepng() */ @@ -277,8 +286,10 @@ trait QROptionsTrait{ protected string $imagickFormat = 'png32'; /** - * Imagick background color (defaults to "transparent") + * Imagick background color * + * @deprecated 5.0.0 use QROptions::$bgColor instead + * @see \chillerlan\QRCode\QROptions::$bgColor * @see \ImagickPixel::__construct() */ protected ?string $imagickBG = null; diff --git a/tests/Output/QRMarkupTestAbstract.php b/tests/Output/QRMarkupTestAbstract.php index a4b05890b..27dfe066e 100644 --- a/tests/Output/QRMarkupTestAbstract.php +++ b/tests/Output/QRMarkupTestAbstract.php @@ -22,7 +22,7 @@ abstract class QRMarkupTestAbstract extends QROutputTestAbstract{ */ public function testSetModuleValues():void{ $this->options->imageBase64 = false; - $this->options->imageTransparent = false; + $this->options->drawLightModules = true; $this->options->moduleValues = [ // data QRMatrix::M_DATA | QRMatrix::IS_DARK => '#4A6000',