mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-21 03:30:24 +00:00
:octocat: add logo space creation
This commit is contained in:
@@ -16,9 +16,6 @@ use chillerlan\QRCode\Output\{QRCodeOutputException, QRImage};
|
||||
|
||||
use function imagecopyresampled, imagecreatefrompng, imagesx, imagesy, is_file, is_readable;
|
||||
|
||||
/**
|
||||
* @property \chillerlan\QRCodeExamples\LogoOptions $options
|
||||
*/
|
||||
class QRImageWithLogo extends QRImage{
|
||||
|
||||
/**
|
||||
@@ -38,12 +35,6 @@ class QRImageWithLogo extends QRImage{
|
||||
throw new QRCodeOutputException('invalid logo');
|
||||
}
|
||||
|
||||
$this->matrix->setLogoSpace(
|
||||
$this->options->logoSpaceWidth,
|
||||
$this->options->logoSpaceHeight
|
||||
// not utilizing the position here
|
||||
);
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
|
||||
+10
-20
@@ -14,27 +14,17 @@ use chillerlan\QRCode\Common\EccLevel;
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
/**
|
||||
* @property int $logoSpaceWidth
|
||||
* @property int $logoSpaceHeight
|
||||
*
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
class LogoOptions extends QROptions{
|
||||
// size in QR modules, multiply with QROptions::$scale for pixel size
|
||||
protected int $logoSpaceWidth;
|
||||
protected int $logoSpaceHeight;
|
||||
}
|
||||
|
||||
$options = new LogoOptions;
|
||||
|
||||
$options->version = 7;
|
||||
$options->eccLevel = EccLevel::H;
|
||||
$options->imageBase64 = false;
|
||||
$options->logoSpaceWidth = 13;
|
||||
$options->logoSpaceWidth = 13;
|
||||
$options->scale = 5;
|
||||
$options->imageTransparent = false;
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'eccLevel' => EccLevel::H,
|
||||
'imageBase64' => false,
|
||||
'addLogoSpace' => true,
|
||||
'logoSpaceWidth' => 13,
|
||||
'logoSpaceHeight' => 13,
|
||||
'scale' => 5,
|
||||
'imageTransparent' => false,
|
||||
]);
|
||||
|
||||
$qrcode = new QRCode($options);
|
||||
$qrcode->addByteSegment($data);
|
||||
|
||||
@@ -161,6 +161,16 @@ class QRCode{
|
||||
|
||||
$matrix = $dataInterface->writeMatrix($maskPattern);
|
||||
|
||||
// add matrix modifications after mask pattern evaluation and before handing over to output
|
||||
if($this->options->addLogoSpace){
|
||||
$matrix->setLogoSpace(
|
||||
$this->options->logoSpaceWidth,
|
||||
$this->options->logoSpaceHeight,
|
||||
$this->options->logoSpaceStartX,
|
||||
$this->options->logoSpaceStartY
|
||||
);
|
||||
}
|
||||
|
||||
if($this->options->addQuietzone){
|
||||
$matrix->setQuietZone($this->options->quietzoneSize);
|
||||
}
|
||||
|
||||
@@ -284,6 +284,31 @@ trait QROptionsTrait{
|
||||
*/
|
||||
protected bool $readerIncreaseContrast = false;
|
||||
|
||||
/**
|
||||
* Toggles logo space creation
|
||||
*/
|
||||
protected bool $addLogoSpace = false;
|
||||
|
||||
/**
|
||||
* width of the logo space
|
||||
*/
|
||||
protected int $logoSpaceWidth = 0;
|
||||
|
||||
/**
|
||||
* height of the logo space
|
||||
*/
|
||||
protected int $logoSpaceHeight = 0;
|
||||
|
||||
/**
|
||||
* optional horizontal start position of the logo space (top left corner)
|
||||
*/
|
||||
protected ?int $logoSpaceStartX = null;
|
||||
|
||||
/**
|
||||
* optional vertical start position of the logo space (top left corner)
|
||||
*/
|
||||
protected ?int $logoSpaceStartY = null;
|
||||
|
||||
/**
|
||||
* clamp min/max version number
|
||||
*/
|
||||
@@ -412,4 +437,39 @@ trait QROptionsTrait{
|
||||
: GDLuminanceSource::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp the logo space values between 0 and maximum length (177 modules at version 40)
|
||||
*/
|
||||
protected function clampLogoSpaceValue(int $value):int{
|
||||
return (int)max(0, min(177, $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp/set logo space width
|
||||
*/
|
||||
protected function set_logoSpaceWidth(int $value):void{
|
||||
$this->logoSpaceWidth = $this->clampLogoSpaceValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp/set logo space height
|
||||
*/
|
||||
protected function set_logoSpaceHeight(int $value):void{
|
||||
$this->logoSpaceHeight = $this->clampLogoSpaceValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp/set horizontal logo space start
|
||||
*/
|
||||
protected function set_logoSpaceStartX(?int $value):void{
|
||||
$this->logoSpaceStartX = $value === null ? null : $this->clampLogoSpaceValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* clamp/set vertical logo space start
|
||||
*/
|
||||
protected function set_logoSpaceStartY(?int $value):void{
|
||||
$this->logoSpaceStartY = $value === null ? null : $this->clampLogoSpaceValue($value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -139,4 +139,51 @@ class QROptionsTest extends TestCase{
|
||||
$o = new QROptions(['imageTransparencyBG' => ['r', 'g', 'b']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[][]
|
||||
*/
|
||||
public function logoSpaceValueProvider():array{
|
||||
return [
|
||||
'negative' => [ -1, 0],
|
||||
'zero' => [ 0, 0],
|
||||
'normal' => [ 69, 69],
|
||||
'max' => [177, 177],
|
||||
'exceed' => [178, 177],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the clamping (between 0 and 177) of the logo space values
|
||||
*
|
||||
* @dataProvider logoSpaceValueProvider
|
||||
*/
|
||||
public function testClampLogoSpaceValue(int $value, int $expected):void{
|
||||
$o = new QROptions;
|
||||
|
||||
foreach(['logoSpaceWidth', 'logoSpaceHeight', 'logoSpaceStartX', 'logoSpaceStartY'] as $prop){
|
||||
$o->{$prop} = $value;
|
||||
$this::assertSame($expected, $o->{$prop});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the optional logo space start values are nullable
|
||||
*/
|
||||
public function testLogoSpaceStartNullable():void{
|
||||
$o = new QROptions([
|
||||
'logoSpaceStartX' => 42,
|
||||
'logoSpaceStartY' => 69,
|
||||
]);
|
||||
|
||||
$this::assertSame(42, $o->logoSpaceStartX);
|
||||
$this::assertSame(69, $o->logoSpaceStartY);
|
||||
|
||||
$o->logoSpaceStartX = null;
|
||||
$o->logoSpaceStartY = null;
|
||||
|
||||
$this::assertNull($o->logoSpaceStartX);
|
||||
$this::assertNull($o->logoSpaceStartY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user