Procházet zdrojové kódy

:sparkles: +imagick output

codemasher před 7 roky
rodič
revize
0cfd4fb3a6

+ 60 - 0
examples/imagick.php

@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * @filesource   image.php
+ * @created      24.12.2017
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2017 Smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+	'version'      => 7,
+	'outputType'   => QRCode::OUTPUT_IMAGICK,
+	'eccLevel'     => QRCode::ECC_L,
+	'scale'        => 5,
+	'imageBase64'  => false,
+	'moduleValues' => [
+		// finder
+		1536 => '#A71111', // dark (true)
+		6    => '#FFBFBF', // light (false)
+		// alignment
+		2560 => '#A70364',
+		10   => '#FFC9C9',
+		// timing
+		3072 => '#98005D',
+		12   => '#FFB8E9',
+		// format
+		3584 => '#003804',
+		14   => '#00FB12',
+		// version
+		4096 => '#650098',
+		16   => '#E0B8FF',
+		// data
+		1024 => '#4A6000',
+		4    => '#ECF9BE',
+		// darkmodule
+		512  => '#080063',
+		// separator
+		8    => '#DDDDDD',
+		// quietzone
+		18   => '#DDDDDD',
+	],
+]);
+
+header('Content-type: image/png');
+
+echo (new QRCode($options))->render($data);
+
+
+
+
+

+ 97 - 0
src/Output/QRImagick.php

@@ -0,0 +1,97 @@
+<?php
+/**
+ * Class QRImagick
+ *
+ * @filesource   QRImagick.php
+ * @created      04.07.2018
+ * @package      chillerlan\QRCode\Output
+ * @author       smiley <smiley@chillerlan.net>
+ * @copyright    2018 smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use Imagick, ImagickDraw, ImagickPixel;
+
+/**
+ * ImageMagick output module
+ * requires ext-imagick
+ * @link http://php.net/manual/book.imagick.php
+ * @link http://phpimagick.com
+ */
+class QRImagick extends QROutputAbstract{
+
+	/**
+	 * @return void
+	 */
+	protected function setModuleValues():void{
+
+		foreach($this::DEFAULT_MODULE_VALUES as $type => $defaultValue){
+			$v = $this->options->moduleValues[$type] ?? null;
+
+			if(!is_string($v)){
+				$this->moduleValues[$type] = $defaultValue
+					? new ImagickPixel($this->options->markupDark)
+					: new ImagickPixel($this->options->markupLight);
+			}
+			else{
+				$this->moduleValues[$type] = new ImagickPixel($v);
+			}
+		}
+	}
+
+	/**
+	 * @param string|null $file
+	 *
+	 * @return string
+	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+	 */
+	public function dump(string $file = null):string{
+		$file    = $file ?? $this->options->cachefile;
+		$imagick = new Imagick;
+
+		$imagick->newImage(
+			$this->length,
+			$this->length,
+			new ImagickPixel($this->options->imagickBG ?? 'transparent'),
+			$this->options->imagickFormat
+		);
+
+		$imageData = $this->drawImage($imagick);
+
+		if($file !== null){
+			$this->saveToFile($imageData, $file);
+		}
+
+		return $imageData;
+	}
+
+	/**
+	 * @param \Imagick $imagick
+	 *
+	 * @return string
+	 */
+	protected function drawImage(Imagick $imagick):string{
+		$draw = new ImagickDraw;
+
+		foreach($this->matrix->matrix() as $y => $row){
+			foreach($row as $x => $M_TYPE){
+				$draw->setStrokeColor($this->moduleValues[$M_TYPE]);
+				$draw->setFillColor($this->moduleValues[$M_TYPE]);
+				$draw->rectangle(
+					$x * $this->scale,
+					$y * $this->scale,
+					($x + 1) * $this->scale,
+					($y + 1) * $this->scale
+				);
+
+			}
+		}
+
+		$imagick->drawImage($draw);
+
+		return (string)$imagick;
+	}
+
+}

+ 7 - 2
src/QRCode.php

@@ -16,7 +16,7 @@ use chillerlan\QRCode\Data\{
 	AlphaNum, Byte, Kanji, MaskPatternTester, Number, QRCodeDataException, QRDataInterface, QRMatrix
 };
 use chillerlan\QRCode\Output\{
-	QRCodeOutputException, QRImage, QRMarkup, QROutputInterface, QRString
+	QRCodeOutputException, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString
 };
 use chillerlan\Settings\SettingsContainerInterface;
 
@@ -44,6 +44,8 @@ class QRCode{
 	const OUTPUT_STRING_JSON  = 'json';
 	const OUTPUT_STRING_TEXT  = 'text';
 
+	const OUTPUT_IMAGICK      = 'imagick';
+
 	const OUTPUT_CUSTOM       = 'custom';
 
 	const VERSION_AUTO        = -1;
@@ -87,7 +89,10 @@ class QRCode{
 		QRString::class => [
 			self::OUTPUT_STRING_JSON,
 			self::OUTPUT_STRING_TEXT,
-		]
+		],
+		QRImagick::class => [
+			self::OUTPUT_IMAGICK,
+		],
 	];
 
 	/**

+ 3 - 0
src/QROptions.php

@@ -46,6 +46,9 @@ use chillerlan\Settings\SettingsContainerAbstract;
  * @property int    $pngCompression
  * @property int    $jpegQuality
  *
+ * @property string $imagickFormat
+ * @property string $imagickBG
+ *
  * @property array  $moduleValues
  */
 class QROptions extends SettingsContainerAbstract{

+ 19 - 1
src/QROptionsTrait.php

@@ -200,10 +200,28 @@ trait QROptionsTrait{
 	 */
 	protected $jpegQuality = 85;
 
+	/**
+	 * Imagick output format
+	 *
+	 * @see Imagick::setType()
+	 *
+	 * @var string
+	 */
+	protected $imagickFormat = 'png';
+
+	/**
+	 * Imagick background color (defaults to "transparent")
+	 *
+	 * @see \ImagickPixel::__construct()
+	 *
+	 * @var string
+	 */
+	protected $imagickBG;
+
 	/**
 	 * Module values map
 	 *
-	 *   HTML : #ABCDEF, cssname, rgb(), rgba()...
+	 *   HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()...
 	 *   IMAGE: [63, 127, 255] // R, G, B
 	 *
 	 * @var array

+ 32 - 0
tests/Output/QRImagickTest.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Class QRImagickTest
+ *
+ * @filesource   QRImagickTest.php
+ * @created      04.07.2018
+ * @package      chillerlan\QRCodeTest\Output
+ * @author       smiley <smiley@chillerlan.net>
+ * @copyright    2018 smiley
+ * @license      MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use chillerlan\QRCode\{QRCode, Output\QRImagick};
+
+class QRImagickTest extends QROutputTestAbstract{
+
+	protected $FQCN = QRImagick::class;
+
+	public function testImageOutput(){
+		$type = QRCode::OUTPUT_IMAGICK;
+
+		$this->options->outputType = $type;
+		$this->setOutputInterface();
+		$this->outputInterface->dump($this::cachefile.$type);
+		$img = $this->outputInterface->dump();
+
+		$this->assertSame($img, file_get_contents($this::cachefile.$type));
+	}
+
+}