smiley 10 лет назад
Родитель
Сommit
b70f028329
3 измененных файлов с 77 добавлено и 70 удалено
  1. 50 67
      src/Output/QRImage.php
  2. 24 0
      src/Output/QRImageOptions.php
  3. 3 3
      src/QRCode.php

+ 50 - 67
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));
 
-	/**
-	 * 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
-	 */
-	public function toImage($size = 2, $margin = 2, $fg = 0x000000, $bg = 0xFFFFFF, $bgtrans = false){
-
-		// 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;
+		foreach(['fgRed', 'fgGreen', 'fgBlue', 'bgRed', 'bgGreen', 'bgBlue',] as $val){
+			$this->options->{$val} = max(0, min(255, (int)$this->options->{$val}));
 		}
 
-		$image_size = $this->pixelCount * $size + $margin * 2;
+		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;
+		}
 
-		$image = imagecreatetruecolor($image_size, $image_size);
+		$this->options->transparent = (bool)$this->options->transparent && $this->options->type !== QRCode::OUTPUT_IMAGE_JPG;
 
-		// fg/bg EC
-		if($fg < 0 || $fg > 0xFFFFFF){
-			$fg = 0x0;
+		if(!in_array($this->options->pngCompression, range(-1, 9), true)){
+			$this->options->pngCompression = -1;
 		}
-		if($bg < 0 || $bg > 0xFFFFFF){
-			$bg = 0xFFFFFF;
+
+		if(!in_array($this->options->jpegQuality, range(0, 100), true)){
+			$this->options->jpegQuality = 85;
 		}
 
-		// 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);
+	/**
+	 * @return mixed
+	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+	 */
+	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);
+
+		if($this->options->transparent){
+			imagecolortransparent($image, $background);
 		}
 
-		// 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;
-	}
-
-	public function dump(){
-		return $this->toImage();
-	}
+		ob_start();
 
-	protected function toPNG(){
+		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();
 
-	/**
-	 * Actually, it's pronounced "DJIFF". *hides*
-	 */
-	protected function toGIF(){
+		if((bool)$this->options->base64){
+			$imageData = 'data:image/'.$this->options->type.';base64,'.base64_encode($imageData);
+		}
 
+		return $imageData;
 	}
+
 }

+ 24 - 0
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;
+
 }

+ 3 - 3
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%.