mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-19 18:20:17 +00:00
:octocat: examples cleanup
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class MyCustomOutput
|
||||
*
|
||||
* @created 24.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\QROutputAbstract;
|
||||
|
||||
class MyCustomOutput extends QROutputAbstract{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function moduleValueIsValid($value):bool{
|
||||
// TODO: Implement moduleValueIsValid() method. (abstract)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getModuleValue($value){
|
||||
// TODO: Implement getModuleValue() method. (abstract)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getDefaultModuleValue(bool $isDark){
|
||||
// TODO: Implement getDefaultModuleValue() method. (abstract)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dump(string $file = null):string{
|
||||
$output = '';
|
||||
|
||||
for($y = 0; $y < $this->moduleCount; $y++){
|
||||
for($x = 0; $x < $this->moduleCount; $x++){
|
||||
$output .= (int)$this->matrix->check($x, $y);
|
||||
}
|
||||
|
||||
$output .= $this->options->eol;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImageWithLogo
|
||||
*
|
||||
* @created 18.11.2020
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2020 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\{QRGdImage, QRCodeOutputException};
|
||||
|
||||
use function imagecopyresampled, imagecreatefrompng, imagesx, imagesy, is_file, is_readable;
|
||||
|
||||
class QRImageWithLogo extends QRGdImage{
|
||||
|
||||
/**
|
||||
* @param string|null $file
|
||||
* @param string|null $logo
|
||||
*
|
||||
* @return string
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
public function dump(string $file = null, string $logo = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// of course you could accept other formats too (such as resource or Imagick)
|
||||
// i'm not checking for the file type either for simplicity reasons (assuming PNG)
|
||||
if(!is_file($logo) || !is_readable($logo)){
|
||||
throw new QRCodeOutputException('invalid logo');
|
||||
}
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
$im = imagecreatefrompng($logo);
|
||||
|
||||
// get logo image size
|
||||
$w = imagesx($im);
|
||||
$h = imagesy($im);
|
||||
|
||||
// set new logo size, leave a border of 1 module (no proportional resize/centering)
|
||||
$lw = ($this->options->logoSpaceWidth - 2) * $this->options->scale;
|
||||
$lh = ($this->options->logoSpaceHeight - 2) * $this->options->scale;
|
||||
|
||||
// get the qrcode size
|
||||
$ql = $this->matrix->size() * $this->options->scale;
|
||||
|
||||
// scale the logo and copy it over. done!
|
||||
imagecopyresampled($this->image, $im, ($ql - $lw) / 2, ($ql - $lh) / 2, 0, 0, $lw, $lh, $w, $h);
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = $this->base64encode($imageData, 'image/'.$this->options->outputType);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImageWithText
|
||||
*
|
||||
* example for additional text
|
||||
*
|
||||
* @link https://github.com/chillerlan/php-qrcode/issues/35
|
||||
*
|
||||
* @created 22.06.2019
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2019 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\QRGdImage;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use function imagechar, imagecolorallocate, imagecolortransparent, imagecopymerge, imagecreatetruecolor,
|
||||
imagedestroy, imagefilledrectangle, imagefontwidth, round, str_split, strlen;
|
||||
|
||||
class QRImageWithText extends QRGdImage{
|
||||
|
||||
/**
|
||||
* @param string|null $file
|
||||
* @param string|null $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump(string $file = null, string $text = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
// render text output if a string is given
|
||||
if($text !== null){
|
||||
$this->addText($text);
|
||||
}
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = $this->base64encode($imageData, 'image/'.$this->options->outputType);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*/
|
||||
protected function addText(string $text):void{
|
||||
// save the qrcode image
|
||||
$qrcode = $this->image;
|
||||
|
||||
// options things
|
||||
$textSize = 3; // see imagefontheight() and imagefontwidth()
|
||||
$textBG = [200, 200, 200];
|
||||
$textColor = [50, 50, 50];
|
||||
|
||||
$bgWidth = $this->length;
|
||||
$bgHeight = $bgWidth + 20; // 20px extra space
|
||||
|
||||
// create a new image with additional space
|
||||
$this->image = imagecreatetruecolor($bgWidth, $bgHeight);
|
||||
$background = imagecolorallocate($this->image, ...$textBG);
|
||||
|
||||
// allow transparency
|
||||
if($this->options->imageTransparent && $this->options->outputType !== QRCode::OUTPUT_IMAGE_JPG){
|
||||
imagecolortransparent($this->image, $background);
|
||||
}
|
||||
|
||||
// fill the background
|
||||
imagefilledrectangle($this->image, 0, 0, $bgWidth, $bgHeight, $background);
|
||||
|
||||
// copy over the qrcode
|
||||
imagecopymerge($this->image, $qrcode, 0, 0, 0, 0, $this->length, $this->length, 100);
|
||||
imagedestroy($qrcode);
|
||||
|
||||
$fontColor = imagecolorallocate($this->image, ...$textColor);
|
||||
$w = imagefontwidth($textSize);
|
||||
$x = round(($bgWidth - strlen($text) * $w) / 2);
|
||||
|
||||
// loop through the string and draw the letters
|
||||
foreach(str_split($text) as $i => $chr){
|
||||
imagechar($this->image, $textSize, (int)($i * $w + $x), $this->length, $chr, $fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRSvgWithLogo
|
||||
*
|
||||
* @created 05.03.2022
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2022 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\QRMarkupSVG;
|
||||
use function ceil, file_get_contents, sprintf;
|
||||
|
||||
/**
|
||||
* Create SVG QR Codes with embedded logos (that are also SVG)
|
||||
*/
|
||||
class QRSvgWithLogo extends QRMarkupSVG{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function paths():string{
|
||||
$size = (int)ceil($this->moduleCount * $this->options->svgLogoScale);
|
||||
|
||||
// we're calling QRMatrix::setLogoSpace() manually, so QROptions::$addLogoSpace has no effect here
|
||||
$this->matrix->setLogoSpace($size, $size);
|
||||
|
||||
$svg = parent::paths();
|
||||
$svg .= $this->getLogo();
|
||||
|
||||
return $svg;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a <g> element that contains the SVG logo and positions it properly within the QR Code
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform
|
||||
*/
|
||||
protected function getLogo():string{
|
||||
// @todo: customize the <g> element to your liking (css class, style...)
|
||||
return sprintf(
|
||||
'%5$s<g transform="translate(%1$s %1$s) scale(%2$s)" class="%3$s">%5$s %4$s%5$s</g>',
|
||||
($this->moduleCount - ($this->moduleCount * $this->options->svgLogoScale)) / 2,
|
||||
$this->options->svgLogoScale,
|
||||
$this->options->svgLogoCssClass,
|
||||
file_get_contents($this->options->svgLogo),
|
||||
$this->options->eol
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,15 +4,70 @@
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use chillerlan\QRCode\Output\QROutputAbstract;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class MyCustomOutput extends QROutputAbstract{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function moduleValueIsValid($value):bool{
|
||||
// TODO: Implement moduleValueIsValid() method. (abstract)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getModuleValue($value){
|
||||
// TODO: Implement getModuleValue() method. (abstract)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getDefaultModuleValue(bool $isDark){
|
||||
// TODO: Implement getDefaultModuleValue() method. (abstract)
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dump(string $file = null):string{
|
||||
$output = '';
|
||||
|
||||
for($y = 0; $y < $this->moduleCount; $y++){
|
||||
for($x = 0; $x < $this->moduleCount; $x++){
|
||||
$output .= (int)$this->matrix->check($x, $y);
|
||||
}
|
||||
|
||||
$output .= $this->options->eol;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Runtime
|
||||
*/
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
// invoke the QROutputInterface manually
|
||||
@@ -29,7 +84,7 @@ $qrOutputInterface = new MyCustomOutput($options, $qrcode->getMatrix());
|
||||
var_dump($qrOutputInterface->dump());
|
||||
|
||||
|
||||
// or just
|
||||
// or just via the options
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'eccLevel' => EccLevel::L,
|
||||
@@ -38,3 +93,5 @@ $options = new QROptions([
|
||||
]);
|
||||
|
||||
var_dump((new QRCode($options))->render($data));
|
||||
|
||||
exit;
|
||||
|
||||
+10
-9
@@ -6,23 +6,19 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_EPS,
|
||||
'eccLevel' => EccLevel::L,
|
||||
'scale' => 5,
|
||||
'addQuietzone' => true,
|
||||
'cachefile' => __DIR__.'/test.eps',
|
||||
# 'cachefile' => __DIR__.'/test.eps', // save to file
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
QRMatrix::M_FINDER | QRMatrix::IS_DARK => 0xA71111, // dark (true)
|
||||
@@ -52,11 +48,16 @@ $options = new QROptions([
|
||||
],
|
||||
]);
|
||||
|
||||
// if viewed in the browser, we should push it as file download as EPS isn't usually supported
|
||||
header('Content-type: application/postscript');
|
||||
header('Content-Disposition: filename="qrcode.eps"');
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
// if viewed in the browser, we should push it as file download as EPS isn't usually supported
|
||||
header('Content-type: application/postscript');
|
||||
header('Content-Disposition: filename="qrcode.eps"');
|
||||
}
|
||||
|
||||
echo (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
|
||||
|
||||
+11
-6
@@ -1,6 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
/**
|
||||
* @created 03.06.2020
|
||||
* @author Maximilian Kresse
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
@@ -8,8 +11,6 @@ use chillerlan\QRCode\Common\EccLevel;
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_FPDF,
|
||||
@@ -44,6 +45,10 @@ $options = new QROptions([
|
||||
],
|
||||
]);
|
||||
|
||||
\header('Content-type: application/pdf');
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
header('Content-type: application/pdf');
|
||||
}
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
echo (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
exit;
|
||||
|
||||
+29
-33
@@ -6,8 +6,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
@@ -16,36 +14,6 @@ require_once '../vendor/autoload.php';
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>QRCode test</title>
|
||||
<style>
|
||||
div.qrcode{
|
||||
margin: 5em;
|
||||
}
|
||||
|
||||
/* rows */
|
||||
div.qrcode > div {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* modules */
|
||||
div.qrcode > div > span {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'outputType' => QRCode::OUTPUT_MARKUP_HTML,
|
||||
@@ -80,7 +48,35 @@ header('Content-Type: text/html; charset=utf-8');
|
||||
],
|
||||
]);
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>QRCode test</title>
|
||||
<style>
|
||||
div.qrcode{
|
||||
margin: 5em;
|
||||
}
|
||||
|
||||
/* rows */
|
||||
div.qrcode > div {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* modules */
|
||||
div.qrcode > div > span {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
echo (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
?>
|
||||
</body>
|
||||
|
||||
+3
-10
@@ -6,17 +6,12 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use Throwable;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
|
||||
@@ -58,8 +53,9 @@ $options = new QROptions([
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
try{
|
||||
$im = (new QRCode($options))->render($data);
|
||||
$im = (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
}
|
||||
catch(Throwable $e){
|
||||
exit($e->getMessage());
|
||||
@@ -69,7 +65,4 @@ header('Content-type: image/png');
|
||||
|
||||
echo $im;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
exit;
|
||||
|
||||
@@ -4,17 +4,77 @@
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2020 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection, PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Output\{QRGdImage, QRCodeOutputException};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://github.com';
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class QRImageWithLogo extends QRGdImage{
|
||||
|
||||
/**
|
||||
* @param string|null $file
|
||||
* @param string|null $logo
|
||||
*
|
||||
* @return string
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
public function dump(string $file = null, string $logo = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// of course you could accept other formats too (such as resource or Imagick)
|
||||
// i'm not checking for the file type either for simplicity reasons (assuming PNG)
|
||||
if(!is_file($logo) || !is_readable($logo)){
|
||||
throw new QRCodeOutputException('invalid logo');
|
||||
}
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
$im = imagecreatefrompng($logo);
|
||||
|
||||
// get logo image size
|
||||
$w = imagesx($im);
|
||||
$h = imagesy($im);
|
||||
|
||||
// set new logo size, leave a border of 1 module (no proportional resize/centering)
|
||||
$lw = ($this->options->logoSpaceWidth - 2) * $this->options->scale;
|
||||
$lh = ($this->options->logoSpaceHeight - 2) * $this->options->scale;
|
||||
|
||||
// get the qrcode size
|
||||
$ql = $this->matrix->size() * $this->options->scale;
|
||||
|
||||
// scale the logo and copy it over. done!
|
||||
imagecopyresampled($this->image, $im, ($ql - $lw) / 2, ($ql - $lh) / 2, 0, 0, $lw, $lh, $w, $h);
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = $this->base64encode($imageData, 'image/'.$this->options->outputType);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Runtime
|
||||
*/
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
@@ -31,11 +91,14 @@ $options = new QROptions([
|
||||
]);
|
||||
|
||||
$qrcode = new QRCode($options);
|
||||
$qrcode->addByteSegment($data);
|
||||
$qrcode->addByteSegment('https://github.com');
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
$qrOutputInterface = new QRImageWithLogo($options, $qrcode->getMatrix());
|
||||
|
||||
// dump the output, with an additional logo
|
||||
// the logo could also be supplied via the options, see the svgWithLogo example
|
||||
echo $qrOutputInterface->dump(null, __DIR__.'/octocat.png');
|
||||
|
||||
exit;
|
||||
|
||||
@@ -7,15 +7,96 @@
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2019 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpIllegalPsrClassPathInspection, PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Output\QRGdImage;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class QRImageWithText extends QRGdImage{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dump(string $file = null, string $text = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
// render text output if a string is given
|
||||
if($text !== null){
|
||||
$this->addText($text);
|
||||
}
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = $this->base64encode($imageData, 'image/'.$this->options->outputType);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function addText(string $text):void{
|
||||
// save the qrcode image
|
||||
$qrcode = $this->image;
|
||||
|
||||
// options things
|
||||
$textSize = 3; // see imagefontheight() and imagefontwidth()
|
||||
$textBG = [200, 200, 200];
|
||||
$textColor = [50, 50, 50];
|
||||
|
||||
$bgWidth = $this->length;
|
||||
$bgHeight = $bgWidth + 20; // 20px extra space
|
||||
|
||||
// create a new image with additional space
|
||||
$this->image = imagecreatetruecolor($bgWidth, $bgHeight);
|
||||
$background = imagecolorallocate($this->image, ...$textBG);
|
||||
|
||||
// allow transparency
|
||||
if($this->options->imageTransparent && $this->options->outputType !== QRCode::OUTPUT_IMAGE_JPG){
|
||||
imagecolortransparent($this->image, $background);
|
||||
}
|
||||
|
||||
// fill the background
|
||||
imagefilledrectangle($this->image, 0, 0, $bgWidth, $bgHeight, $background);
|
||||
|
||||
// copy over the qrcode
|
||||
imagecopymerge($this->image, $qrcode, 0, 0, 0, 0, $this->length, $this->length, 100);
|
||||
imagedestroy($qrcode);
|
||||
|
||||
$fontColor = imagecolorallocate($this->image, ...$textColor);
|
||||
$w = imagefontwidth($textSize);
|
||||
$x = round(($bgWidth - strlen($text) * $w) / 2);
|
||||
|
||||
// loop through the string and draw the letters
|
||||
foreach(str_split($text) as $i => $chr){
|
||||
imagechar($this->image, $textSize, (int)($i * $w + $x), $this->length, $chr, $fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Runtime
|
||||
*/
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
@@ -25,11 +106,14 @@ $options = new QROptions([
|
||||
]);
|
||||
|
||||
$qrcode = new QRCode($options);
|
||||
$qrcode->addByteSegment($data);
|
||||
$qrcode->addByteSegment('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
$qrOutputInterface = new QRImageWithText($options, $qrcode->getMatrix());
|
||||
|
||||
// dump the output, with additional text
|
||||
// the text could also be supplied via the options, see the svgWithLogo example
|
||||
echo $qrOutputInterface->dump(null, 'example text');
|
||||
|
||||
exit;
|
||||
|
||||
@@ -6,16 +6,12 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_IMAGICK,
|
||||
@@ -56,9 +52,6 @@ $options = new QROptions([
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
|
||||
|
||||
|
||||
|
||||
echo (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
exit;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodePublic;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
@@ -86,11 +86,13 @@ try{
|
||||
send_response(['qrcode' => $qrcode]);
|
||||
}
|
||||
// Pokémon exception handler
|
||||
catch(\Exception $e){
|
||||
catch(Throwable $e){
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
send_response(['error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
/**
|
||||
* @param array $response
|
||||
*/
|
||||
|
||||
+2
-2
@@ -8,8 +8,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
@@ -23,3 +21,5 @@ $options->readerIncreaseContrast = true;
|
||||
$result = (new QRCode($options))->readFromFile(__DIR__.'/../.github/images/example_image.png');
|
||||
|
||||
var_dump($result);
|
||||
|
||||
exit;
|
||||
|
||||
+10
-12
@@ -9,18 +9,12 @@
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use function gzencode, header;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
|
||||
$gzip = true;
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
|
||||
@@ -59,14 +53,18 @@ $options = new QROptions([
|
||||
]]></style>',
|
||||
]);
|
||||
|
||||
$qrcode = (new QRCode($options))->render($data);
|
||||
$qrcode = (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
header('Content-type: image/svg+xml');
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
header('Content-type: image/svg+xml');
|
||||
|
||||
if($gzip){
|
||||
header('Vary: Accept-Encoding');
|
||||
header('Content-Encoding: gzip');
|
||||
$qrcode = gzencode($qrcode, 9);
|
||||
if(extension_loaded('zlib')){
|
||||
header('Vary: Accept-Encoding');
|
||||
header('Content-Encoding: gzip');
|
||||
$qrcode = gzencode($qrcode, 9);
|
||||
}
|
||||
}
|
||||
|
||||
echo $qrcode;
|
||||
|
||||
exit;
|
||||
|
||||
+92
-40
@@ -8,19 +8,94 @@
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QRCodeException, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
use function file_exists, gzencode, header, is_readable, max, min;
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Output\QRMarkupSVG;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
|
||||
$gzip = true;
|
||||
/*
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
$options_arr = [
|
||||
/**
|
||||
* Create SVG QR Codes with embedded logos (that are also SVG)
|
||||
*/
|
||||
class QRSvgWithLogo extends QRMarkupSVG{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function paths():string{
|
||||
$size = (int)ceil($this->moduleCount * $this->options->svgLogoScale);
|
||||
|
||||
// we're calling QRMatrix::setLogoSpace() manually, so QROptions::$addLogoSpace has no effect here
|
||||
$this->matrix->setLogoSpace($size, $size);
|
||||
|
||||
$svg = parent::paths();
|
||||
$svg .= $this->getLogo();
|
||||
|
||||
return $svg;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a <g> element that contains the SVG logo and positions it properly within the QR Code
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform
|
||||
*/
|
||||
protected function getLogo():string{
|
||||
// @todo: customize the <g> element to your liking (css class, style...)
|
||||
return sprintf(
|
||||
'%5$s<g transform="translate(%1$s %1$s) scale(%2$s)" class="%3$s">%5$s %4$s%5$s</g>',
|
||||
($this->moduleCount - ($this->moduleCount * $this->options->svgLogoScale)) / 2,
|
||||
$this->options->svgLogoScale,
|
||||
$this->options->svgLogoCssClass,
|
||||
file_get_contents($this->options->svgLogo),
|
||||
$this->options->eol
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* augment the QROptions class
|
||||
*/
|
||||
class SVGWithLogoOptions extends QROptions{
|
||||
// path to svg logo
|
||||
protected string $svgLogo;
|
||||
// logo scale in % of QR Code size, clamped to 10%-30%
|
||||
protected float $svgLogoScale = 0.20;
|
||||
// css class for the logo (defined in $svgDefs)
|
||||
protected string $svgLogoCssClass = '';
|
||||
|
||||
// check logo
|
||||
protected function set_svgLogo(string $svgLogo):void{
|
||||
|
||||
if(!file_exists($svgLogo) || !is_readable($svgLogo)){
|
||||
throw new QRCodeException('invalid svg logo');
|
||||
}
|
||||
|
||||
// @todo: validate svg
|
||||
|
||||
$this->svgLogo = $svgLogo;
|
||||
}
|
||||
|
||||
// clamp logo scale
|
||||
protected function set_svgLogoScale(float $svgLogoScale):void{
|
||||
$this->svgLogoScale = max(0.05, min(0.3, $svgLogoScale));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Runtime
|
||||
*/
|
||||
|
||||
$options = new SVGWithLogoOptions([
|
||||
// SVG logo options (see extended class below)
|
||||
'svgLogo' => __DIR__.'/github.svg', // logo from: https://github.com/simple-icons/simple-icons
|
||||
'svgLogoScale' => 0.25,
|
||||
@@ -60,44 +135,21 @@ $options_arr = [
|
||||
.dark{fill: url(#gradient);}
|
||||
.light{fill: #eaeaea;}
|
||||
]]></style>',
|
||||
];
|
||||
]);
|
||||
|
||||
// augment the QROptions class
|
||||
$options = new class ($options_arr) extends QROptions{
|
||||
// path to svg logo
|
||||
protected string $svgLogo;
|
||||
// logo scale in % of QR Code size, clamped to 10%-30%
|
||||
protected float $svgLogoScale = 0.20;
|
||||
// css class for the logo (defined in $svgDefs)
|
||||
protected string $svgLogoCssClass = '';
|
||||
$qrcode = (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
// check logo
|
||||
protected function set_svgLogo(string $svgLogo):void{
|
||||
|
||||
if(!file_exists($svgLogo) || !is_readable($svgLogo)){
|
||||
throw new QRCodeException('invalid svg logo');
|
||||
}
|
||||
if(php_sapi_name() !== 'cli'){
|
||||
header('Content-type: image/svg+xml');
|
||||
|
||||
// @todo: validate svg
|
||||
|
||||
$this->svgLogo = $svgLogo;
|
||||
if(extension_loaded('zlib')){
|
||||
header('Vary: Accept-Encoding');
|
||||
header('Content-Encoding: gzip');
|
||||
$qrcode = gzencode($qrcode, 9);
|
||||
}
|
||||
|
||||
// clamp logo scale
|
||||
protected function set_svgLogoScale(float $svgLogoScale):void{
|
||||
$this->svgLogoScale = max(0.05, min(0.3, $svgLogoScale));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$qrcode = (new QRCode($options))->render($data);
|
||||
|
||||
header('Content-type: image/svg+xml');
|
||||
|
||||
if($gzip){
|
||||
header('Vary: Accept-Encoding');
|
||||
header('Content-Encoding: gzip');
|
||||
$qrcode = gzencode($qrcode, 9);
|
||||
}
|
||||
|
||||
echo $qrcode;
|
||||
|
||||
exit;
|
||||
|
||||
+3
-5
@@ -8,8 +8,6 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\Common\EccLevel;
|
||||
@@ -17,8 +15,6 @@ use PHPUnit\Util\Color;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_STRING_TEXT,
|
||||
@@ -60,4 +56,6 @@ $options = new QROptions([
|
||||
],
|
||||
]);
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
echo (new QRCode($options))->render('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||
|
||||
exit;
|
||||
|
||||
Reference in New Issue
Block a user