diff --git a/src/Logo/Logo.php b/src/Logo/Logo.php index 7b28a2a..25b316d 100644 --- a/src/Logo/Logo.php +++ b/src/Logo/Logo.php @@ -4,13 +4,18 @@ namespace Endroid\QrCode\Logo; +use Endroid\QrCode\Color\Color; +use Endroid\QrCode\Color\ColorInterface; + final class Logo implements LogoInterface { public function __construct( private string $path, private int|null $resizeToWidth = null, private int|null $resizeToHeight = null, - private bool $punchoutBackground = false + private bool $punchoutBackground = false, + private int $margin = 0, + private ColorInterface $backgroundColor = new Color(255, 255, 255, 127) ) { } @@ -66,4 +71,28 @@ public function setPunchoutBackground(bool $punchoutBackground): self return $this; } + + public function getMargin(): int + { + return $this->margin; + } + + public function setMargin(int $margin): self + { + $this->margin = $margin; + + return $this; + } + + public function getBackgroundColor(): ColorInterface + { + return $this->backgroundColor; + } + + public function setBackgroundColor(ColorInterface $backgroundColor): self + { + $this->backgroundColor = $backgroundColor; + + return $this; + } } diff --git a/src/Logo/LogoInterface.php b/src/Logo/LogoInterface.php index 12036e3..7bc9b1e 100644 --- a/src/Logo/LogoInterface.php +++ b/src/Logo/LogoInterface.php @@ -4,6 +4,8 @@ namespace Endroid\QrCode\Logo; +use Endroid\QrCode\Color\ColorInterface; + interface LogoInterface { public function getPath(): string; @@ -13,4 +15,8 @@ public function getResizeToWidth(): int|null; public function getResizeToHeight(): int|null; public function getPunchoutBackground(): bool; + + public function getMargin(): int; + + public function getBackgroundColor(): ColorInterface; } diff --git a/src/Writer/AbstractGdWriter.php b/src/Writer/AbstractGdWriter.php index a0080ef..7f0444a 100644 --- a/src/Writer/AbstractGdWriter.php +++ b/src/Writer/AbstractGdWriter.php @@ -127,33 +127,53 @@ private function addLogo(LogoInterface $logo, GdResult $result): GdResult throw new \Exception('PNG Writer does not support SVG logo'); } + $logoImage = $logoImageData->getImage(); $targetImage = $result->getImage(); $matrix = $result->getMatrix(); if ($logoImageData->getPunchoutBackground()) { - /** @var int $transparent */ - $transparent = imagecolorallocatealpha($targetImage, 255, 255, 255, 127); - imagealphablending($targetImage, false); - $xOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2); - $yOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2); - for ($xOffset = $xOffsetStart; $xOffset < $xOffsetStart + $logoImageData->getWidth(); ++$xOffset) { - for ($yOffset = $yOffsetStart; $yOffset < $yOffsetStart + $logoImageData->getHeight(); ++$yOffset) { - imagesetpixel($targetImage, $xOffset, $yOffset, $transparent); - } + $logoImage = imagecreatetruecolor($logoImageData->getWidth() + $logo->getMargin() * 2, $logoImageData->getHeight() + $logo->getMargin() * 2); + + if (!$logoImage) { + throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly'); } + + /** @var int $backgroundColor */ + $backgroundColor = imagecolorallocatealpha( + $logoImage, + $logo->getBackgroundColor()->getRed(), + $logo->getBackgroundColor()->getGreen(), + $logo->getBackgroundColor()->getBlue(), + $logo->getBackgroundColor()->getAlpha() + ); + + imagefill($logoImage, 0, 0, $backgroundColor); + + imagecopyresampled( + $logoImage, + $logoImageData->getImage(), + $logo->getMargin(), + $logo->getMargin(), + 0, + 0, + $logoImageData->getWidth(), + $logoImageData->getHeight(), + imagesx($logoImageData->getImage()), + imagesy($logoImageData->getImage()) + ); } imagecopyresampled( $targetImage, - $logoImageData->getImage(), - intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2), - intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2), + $logoImage, + intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2 - $logo->getMargin()), + intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2 - $logo->getMargin()), 0, 0, - $logoImageData->getWidth(), - $logoImageData->getHeight(), - imagesx($logoImageData->getImage()), - imagesy($logoImageData->getImage()) + $logoImageData->getWidth() + $logo->getMargin() * 2, + $logoImageData->getHeight() + $logo->getMargin() * 2, + imagesx($logoImage), + imagesy($logoImage) ); return new GdResult($matrix, $targetImage);