From b70f0283292b7cabab2f48ac5d042cd220cec90d Mon Sep 17 00:00:00 2001 From: smiley Date: Thu, 10 Dec 2015 03:38:10 +0100 Subject: [PATCH] QRImage* --- src/Output/QRImage.php | 133 +++++++++++++++------------------- src/Output/QRImageOptions.php | 24 ++++++ src/QRCode.php | 6 +- 3 files changed, 85 insertions(+), 78 deletions(-) diff --git a/src/Output/QRImage.php b/src/Output/QRImage.php index 8a1a339b7..9161b9f6f 100644 --- a/src/Output/QRImage.php +++ b/src/Output/QRImage.php @@ -11,10 +11,10 @@ */ namespace chillerlan\QRCode\Output; -use chillerlan\QRCode\Util; +use chillerlan\QRCode\QRCode; /** - * toBase64() + * */ class QRImage extends QROutputBase implements QROutputInterface{ @@ -33,95 +33,78 @@ class QRImage extends QROutputBase implements QROutputInterface{ $this->options = new QRImageOptions; } + // clamp input values + // todo: determine sane values + + $this->options->pixelSize = max(1, min(25, (int)$this->options->pixelSize)); + $this->options->marginSize = max(0, min(25, (int)$this->options->marginSize)); + + foreach(['fgRed', 'fgGreen', 'fgBlue', 'bgRed', 'bgGreen', 'bgBlue',] as $val){ + $this->options->{$val} = max(0, min(255, (int)$this->options->{$val})); + } + + if(!in_array($this->options->type, [QRCode::OUTPUT_IMAGE_PNG, QRCode::OUTPUT_IMAGE_JPG, QRCode::OUTPUT_IMAGE_GIF])){ + $this->options->type = QRCode::OUTPUT_IMAGE_PNG; + } + + $this->options->transparent = (bool)$this->options->transparent && $this->options->type !== QRCode::OUTPUT_IMAGE_JPG; + + if(!in_array($this->options->pngCompression, range(-1, 9), true)){ + $this->options->pngCompression = -1; + } + + if(!in_array($this->options->jpegQuality, range(0, 100), true)){ + $this->options->jpegQuality = 85; + } + } - - /** - * added $fg (foreground), $bg (background), and $bgtrans (use transparent bg) parameters - * also added some simple error checking on parameters - * updated 2015.07.27 ~ DoktorJ - * - * @param int $size - * @param int $margin - * @param int $fg - * @param int $bg - * @param bool|false $bgtrans - * - * @return resource + * @return mixed + * @throws \chillerlan\QRCode\Output\QRCodeOutputException */ - public function toImage($size = 2, $margin = 2, $fg = 0x000000, $bg = 0xFFFFFF, $bgtrans = false){ + public function dump(){ + $length = $this->pixelCount * $this->options->pixelSize + $this->options->marginSize * 2; + $image = imagecreatetruecolor($length, $length); + $foreground = imagecolorallocate($image, $this->options->fgRed, $this->options->fgGreen, $this->options->fgBlue); + $background = imagecolorallocate($image, $this->options->bgRed, $this->options->bgGreen, $this->options->bgBlue); - // size/margin EC - if(!is_numeric($size)){ - $size = 2; - } - if(!is_numeric($margin)){ - $margin = 2; - } - if($size < 1){ - $size = 1; - } - if($margin < 0){ - $margin = 0; + if($this->options->transparent){ + imagecolortransparent($image, $background); } - $image_size = $this->pixelCount * $size + $margin * 2; - - $image = imagecreatetruecolor($image_size, $image_size); - - // fg/bg EC - if($fg < 0 || $fg > 0xFFFFFF){ - $fg = 0x0; - } - if($bg < 0 || $bg > 0xFFFFFF){ - $bg = 0xFFFFFF; - } - - // convert hexadecimal RGB to arrays for imagecolorallocate - $fgrgb = Util::hex2rgb($fg); - $bgrgb = Util::hex2rgb($bg); - - // replace $black and $white with $fgc and $bgc - $fgc = imagecolorallocate($image, $fgrgb['r'], $fgrgb['g'], $fgrgb['b']); - $bgc = imagecolorallocate($image, $bgrgb['r'], $bgrgb['g'], $bgrgb['b']); - if($bgtrans){ - imagecolortransparent($image, $bgc); - } - - // update $white to $bgc - imagefilledrectangle($image, 0, 0, $image_size, $image_size, $bgc); + imagefilledrectangle($image, 0, 0, $length, $length, $background); for($r = 0; $r < $this->pixelCount; $r++){ for($c = 0; $c < $this->pixelCount; $c++){ if($this->matrix[$r][$c]){ - - // update $black to $fgc imagefilledrectangle($image, - $margin + $c * $size, - $margin + $r * $size, - $margin + ($c + 1) * $size - 1, - $margin + ($r + 1) * $size - 1, - $fgc); + $this->options->marginSize + $c * $this->options->pixelSize, + $this->options->marginSize + $r * $this->options->pixelSize, + $this->options->marginSize + ($c + 1) * $this->options->pixelSize - 1, + $this->options->marginSize + ($r + 1) * $this->options->pixelSize - 1, + $foreground); } } } - return $image; + ob_start(); + + switch($this->options->type){ + case QRCode::OUTPUT_IMAGE_PNG: imagepng ($image, $this->options->cachefile, (int)$this->options->pngCompression); break; + case QRCode::OUTPUT_IMAGE_JPG: imagejpeg($image, $this->options->cachefile, (int)$this->options->jpegQuality); break; + case QRCode::OUTPUT_IMAGE_GIF: imagegif ($image, $this->options->cachefile); break; /** Actually, it's pronounced "DJIFF". *hides* */ + } + + $imageData = ob_get_contents(); + imagedestroy($image); + ob_end_clean(); + + if((bool)$this->options->base64){ + $imageData = 'data:image/'.$this->options->type.';base64,'.base64_encode($imageData); + } + + return $imageData; } - public function dump(){ - return $this->toImage(); - } - - protected function toPNG(){ - - } - - /** - * Actually, it's pronounced "DJIFF". *hides* - */ - protected function toGIF(){ - - } } diff --git a/src/Output/QRImageOptions.php b/src/Output/QRImageOptions.php index 80d82dbf4..265a44ab0 100644 --- a/src/Output/QRImageOptions.php +++ b/src/Output/QRImageOptions.php @@ -10,10 +10,34 @@ */ namespace chillerlan\QRCode\Output; +use chillerlan\QRCode\QRCode; /** * Class QRImageOptions */ class QRImageOptions{ + public $type = QRCode::OUTPUT_IMAGE_PNG; + + public $base64 = true; + + public $cachefile = null; + + public $pixelSize = 5; + public $marginSize = 5; + + // not supported by jpg + public $transparent = true; + + public $fgRed = 0; + public $fgGreen = 0; + public $fgBlue = 0; + + public $bgRed = 255; + public $bgGreen = 255; + public $bgBlue = 255; + + public $pngCompression = -1; + public $jpegQuality = 85; + } diff --git a/src/QRCode.php b/src/QRCode.php index 797754908..e1cc8de18 100644 --- a/src/QRCode.php +++ b/src/QRCode.php @@ -26,9 +26,9 @@ class QRCode{ const OUTPUT_STRING_JSON = 1; const OUTPUT_STRING_HTML = 2; - const OUTPUT_IMAGE_PNG = 0; - const OUTPUT_IMAGE_JPG = 1; - const OUTPUT_IMAGE_GIF = 2; + const OUTPUT_IMAGE_PNG = 'png'; + const OUTPUT_IMAGE_JPG = 'jpg'; + const OUTPUT_IMAGE_GIF = 'gif'; const ERROR_CORRECT_LEVEL_L = 1; // 7%. const ERROR_CORRECT_LEVEL_M = 0; // 15%.