diff --git a/examples/Readme.md b/examples/Readme.md index 150bab173..d133735aa 100644 --- a/examples/Readme.md +++ b/examples/Readme.md @@ -20,6 +20,7 @@ - [GD Image with logo](./imageWithLogo.php): a logo on top of the QR Code - [GD image with text](./imageWithText.php): description text under the QR Code ([#35](https://github.com/chillerlan/php-qrcode/issues/35)) - [ImageMagick with logo](./imagickWithLogo.php): a logo on top of the QR Code +- [ImageMagick with image as background](./imagickImageAsBackground.php): an image as full size background of the QR Code - [SVG with logo](./svgWithLogo.php): an SVG QR Code with embedded logo (that is also SVG) - [SVG with "melted" modules](./svgMeltedModules.php): an effect where the matrix appears to be like melted wax ([#127](https://github.com/chillerlan/php-qrcode/issues/127)) - [SVG with randomly colored modules](./svgRandomColoredDots.php): a visual effect using multiple colors for the matrix modules ([#136](https://github.com/chillerlan/php-qrcode/discussions/136)) diff --git a/examples/background.jpg b/examples/background.jpg new file mode 100644 index 000000000..8ea77ab19 Binary files /dev/null and b/examples/background.jpg differ diff --git a/examples/imagickImageAsBackground.php b/examples/imagickImageAsBackground.php new file mode 100644 index 000000000..fe063f0ee --- /dev/null +++ b/examples/imagickImageAsBackground.php @@ -0,0 +1,109 @@ + + * @copyright 2023 smiley + * @license MIT + */ + +use chillerlan\QRCode\Common\EccLevel; +use chillerlan\QRCode\Output\QRImagick; +use chillerlan\QRCode\Output\QROutputInterface; +use chillerlan\QRCode\QRCode; +use chillerlan\QRCode\QRCodeException; +use chillerlan\QRCode\QROptions; + +require_once __DIR__.'/../vendor/autoload.php'; + +class QRImagickImageAsBackground extends QRImagick{ + + /** + * @inheritDoc + */ + protected function createImage():Imagick{ + $imagick = new Imagick($this->options->background); + $width = $imagick->getImageWidth(); + $height = $imagick->getImageHeight(); + + // crop the background if necessary + if(($width / $height) !== 1){ + $cropsize = ($width > $height) ? $height : $width; + + $imagick->cropImage($cropsize, $cropsize, 0, 0); + } + + // scale the background to fit the size of the QR Code + if($imagick->getImageWidth() !== $this->length){ + $imagick->scaleImage($this->length, $this->length, true); + } + + if($this->options->quality > -1){ + $imagick->setImageCompressionQuality(max(0, min(100, $this->options->quality))); + } + + return $imagick; + } + +} + + +/** + * augment the QROptions class + */ +class ImageAsBackgroundOptions extends QROptions{ + + protected string $background; + + /** + * check background image + * + * @throws \chillerlan\QRCode\QRCodeException + */ + protected function set_background(string $background):void{ + + if(!file_exists($background) || !is_file($background) || !is_readable($background)){ + throw new QRCodeException('invalid background file'); + } + + // @todo: check/validate desired image format + + $this->background = $background; + } + +} + + +/* + * Runtime + */ + +$options = new ImageAsBackgroundOptions; + +$options->background = __DIR__.'/background.jpg'; // setting from the augmented options +$options->version = 5; +$options->outputType = QROutputInterface::CUSTOM; +$options->outputInterface = QRImagickImageAsBackground::class; // use the custom output class +$options->eccLevel = EccLevel::H; +$options->outputBase64 = false; +$options->scale = 10; +$options->drawLightModules = true; +$options->markupDark = '#00000040'; // RGBA, adjust opacity to increase contrast +$options->markupLight = '#ffffffa0'; +$options->invertMatrix = false; +$options->quietzoneSize = 1; + + +// dump the output, with an additional logo +$out = (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +if(PHP_SAPI !== 'cli'){ + header('Content-type: image/png'); + + echo $out; +} + +exit; + +