mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-17 14:31:08 +00:00
168 lines
3.9 KiB
PHP
168 lines
3.9 KiB
PHP
<?php
|
|
/**
|
|
* Randomly colored modules example
|
|
*
|
|
* @see https://github.com/chillerlan/php-qrcode/discussions/136
|
|
*
|
|
* @created 09.07.2022
|
|
* @author Smiley <smiley@chillerlan.net>
|
|
* @copyright 2022 Smiley
|
|
* @license MIT
|
|
*
|
|
* @noinspection PhpIllegalPsrClassPathInspection
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
use chillerlan\QRCode\{QRCode, QROptions};
|
|
use chillerlan\QRCode\Common\EccLevel;
|
|
use chillerlan\QRCode\Data\QRMatrix;
|
|
use chillerlan\QRCode\Output\QRMarkupSVG;
|
|
|
|
require_once __DIR__.'/../vendor/autoload.php';
|
|
|
|
/*
|
|
* Class definition
|
|
*/
|
|
|
|
// the extended SVG output module
|
|
class RandomDotsSVGOutput extends QRMarkupSVG{
|
|
|
|
protected function path(string $path, int $M_TYPE):string{
|
|
// omit the "fill" and "opacity" attributes on the path element
|
|
return sprintf('<path class="%s" d="%s"/>', $this->getCssClass($M_TYPE), $path);
|
|
}
|
|
|
|
/**
|
|
* To alter the layer a module appears on, we need to re-implement the collection method
|
|
*
|
|
* @inheritDoc
|
|
*/
|
|
protected function collectModules(Closure $transform):array{
|
|
$paths = [];
|
|
$dotColors = $this->options->dotColors; // avoid magic getter in long loops
|
|
|
|
// collect the modules for each type
|
|
foreach($this->matrix->getMatrix() as $y => $row){
|
|
foreach($row as $x => $M_TYPE){
|
|
$M_TYPE_LAYER = $M_TYPE;
|
|
|
|
if($this->connectPaths && !$this->matrix->checkTypeIn($x, $y, $this->excludeFromConnect)){
|
|
// to connect paths we'll redeclare the $M_TYPE_LAYER to data only
|
|
$M_TYPE_LAYER = QRMatrix::M_DATA;
|
|
|
|
if($this->matrix->isDark($M_TYPE)){
|
|
$M_TYPE_LAYER = QRMatrix::M_DATA_DARK;
|
|
}
|
|
}
|
|
|
|
// randomly assign another $M_TYPE_LAYER for the given types
|
|
// note that the layer id has to be an integer value,
|
|
// ideally outside the several bitmask values
|
|
if($M_TYPE_LAYER === QRMatrix::M_DATA_DARK){
|
|
$M_TYPE_LAYER = array_rand($dotColors);
|
|
}
|
|
|
|
// collect the modules per $M_TYPE
|
|
$module = $transform($x, $y, $M_TYPE, $M_TYPE_LAYER);
|
|
|
|
if(!empty($module)){
|
|
$paths[$M_TYPE_LAYER][] = $module;
|
|
}
|
|
}
|
|
}
|
|
|
|
// beautify output
|
|
ksort($paths);
|
|
|
|
return $paths;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* the extended options with the $dotColors option
|
|
*
|
|
* @property array<int, string> $dotColors
|
|
*/
|
|
class RandomDotsOptions extends QROptions{
|
|
|
|
/**
|
|
* a map of $M_TYPE_LAYER => color
|
|
*
|
|
* @see \array_rand()
|
|
* @var array<int, string>
|
|
*/
|
|
protected array $dotColors = [];
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Runtime
|
|
*/
|
|
|
|
// prepare the options
|
|
$options = new RandomDotsOptions;
|
|
|
|
// our custom dot colors
|
|
// adding the IS_DARK flag so that the proper layer css class is assigned
|
|
$options->dotColors = [
|
|
(111 | QRMatrix::IS_DARK) => '#e2453c',
|
|
(222 | QRMatrix::IS_DARK) => '#e07e39',
|
|
(333 | QRMatrix::IS_DARK) => '#e5d667',
|
|
(444 | QRMatrix::IS_DARK) => '#51b95b',
|
|
(555 | QRMatrix::IS_DARK) => '#1e72b7',
|
|
(666 | QRMatrix::IS_DARK) => '#6f5ba7',
|
|
];
|
|
|
|
// generate the CSS for the several colored layers
|
|
$layerColors = '';
|
|
|
|
foreach($options->dotColors as $layer => $color){
|
|
$layerColors .= sprintf("\n\t\t.qr-%s{ fill: %s; }", $layer, $color);
|
|
}
|
|
|
|
$options->svgDefs = '
|
|
<style><![CDATA[
|
|
.dark{ fill: #424242; }
|
|
'.$layerColors.'
|
|
]]></style>';
|
|
|
|
// set the custom output interface
|
|
$options->outputInterface = RandomDotsSVGOutput::class;
|
|
|
|
// common qrcode options
|
|
$options->version = 5;
|
|
$options->eccLevel = EccLevel::H;
|
|
$options->addQuietzone = true;
|
|
$options->outputBase64 = false;
|
|
$options->drawLightModules = false;
|
|
$options->connectPaths = true;
|
|
$options->excludeFromConnect = [
|
|
QRMatrix::M_FINDER_DARK,
|
|
QRMatrix::M_FINDER_DOT,
|
|
QRMatrix::M_ALIGNMENT_DARK,
|
|
];
|
|
$options->drawCircularModules = true;
|
|
$options->circleRadius = 0.4;
|
|
$options->keepAsSquare = [
|
|
QRMatrix::M_FINDER_DARK,
|
|
QRMatrix::M_FINDER_DOT,
|
|
QRMatrix::M_ALIGNMENT_DARK,
|
|
];
|
|
|
|
|
|
|
|
$out = (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
|
|
|
|
|
// dump the output
|
|
if(PHP_SAPI !== 'cli'){
|
|
header('content-type: image/svg+xml');
|
|
}
|
|
|
|
echo $out;
|
|
|
|
exit;
|