123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <?php
- declare(strict_types = 1);
- namespace BaconQrCode\Renderer;
- use BaconQrCode\Encoder\MatrixUtil;
- use BaconQrCode\Encoder\QrCode;
- use BaconQrCode\Exception\InvalidArgumentException;
- use BaconQrCode\Renderer\Image\ImageBackEndInterface;
- use BaconQrCode\Renderer\Path\Path;
- use BaconQrCode\Renderer\RendererStyle\EyeFill;
- use BaconQrCode\Renderer\RendererStyle\RendererStyle;
- final class ImageRenderer implements RendererInterface
- {
- /**
- * @var RendererStyle
- */
- private $rendererStyle;
- /**
- * @var ImageBackEndInterface
- */
- private $imageBackEnd;
- public function __construct(RendererStyle $rendererStyle, ImageBackEndInterface $imageBackEnd)
- {
- $this->rendererStyle = $rendererStyle;
- $this->imageBackEnd = $imageBackEnd;
- }
- /**
- * @throws InvalidArgumentException if matrix width doesn't match height
- */
- public function render(QrCode $qrCode) : string
- {
- $size = $this->rendererStyle->getSize();
- $margin = $this->rendererStyle->getMargin();
- $matrix = $qrCode->getMatrix();
- $matrixSize = $matrix->getWidth();
- if ($matrixSize !== $matrix->getHeight()) {
- throw new InvalidArgumentException('Matrix must have the same width and height');
- }
- $totalSize = $matrixSize + ($margin * 2);
- $moduleSize = $size / $totalSize;
- $fill = $this->rendererStyle->getFill();
- $this->imageBackEnd->new($size, $fill->getBackgroundColor());
- $this->imageBackEnd->scale((float) $moduleSize);
- $this->imageBackEnd->translate((float) $margin, (float) $margin);
- $module = $this->rendererStyle->getModule();
- $moduleMatrix = clone $matrix;
- MatrixUtil::removePositionDetectionPatterns($moduleMatrix);
- $modulePath = $this->drawEyes($matrixSize, $module->createPath($moduleMatrix));
- if ($fill->hasGradientFill()) {
- $this->imageBackEnd->drawPathWithGradient(
- $modulePath,
- $fill->getForegroundGradient(),
- 0,
- 0,
- $matrixSize,
- $matrixSize
- );
- } else {
- $this->imageBackEnd->drawPathWithColor($modulePath, $fill->getForegroundColor());
- }
- return $this->imageBackEnd->done();
- }
- private function drawEyes(int $matrixSize, Path $modulePath) : Path
- {
- $fill = $this->rendererStyle->getFill();
- $eye = $this->rendererStyle->getEye();
- $externalPath = $eye->getExternalPath();
- $internalPath = $eye->getInternalPath();
- $modulePath = $this->drawEye(
- $externalPath,
- $internalPath,
- $fill->getTopLeftEyeFill(),
- 3.5,
- 3.5,
- 0,
- $modulePath
- );
- $modulePath = $this->drawEye(
- $externalPath,
- $internalPath,
- $fill->getTopRightEyeFill(),
- $matrixSize - 3.5,
- 3.5,
- 90,
- $modulePath
- );
- $modulePath = $this->drawEye(
- $externalPath,
- $internalPath,
- $fill->getBottomLeftEyeFill(),
- 3.5,
- $matrixSize - 3.5,
- -90,
- $modulePath
- );
- return $modulePath;
- }
- private function drawEye(
- Path $externalPath,
- Path $internalPath,
- EyeFill $fill,
- float $xTranslation,
- float $yTranslation,
- int $rotation,
- Path $modulePath
- ) : Path {
- if ($fill->inheritsBothColors()) {
- return $modulePath
- ->append($externalPath->translate($xTranslation, $yTranslation))
- ->append($internalPath->translate($xTranslation, $yTranslation));
- }
- $this->imageBackEnd->push();
- $this->imageBackEnd->translate($xTranslation, $yTranslation);
- if (0 !== $rotation) {
- $this->imageBackEnd->rotate($rotation);
- }
- if ($fill->inheritsExternalColor()) {
- $modulePath = $modulePath->append($externalPath->translate($xTranslation, $yTranslation));
- } else {
- $this->imageBackEnd->drawPathWithColor($externalPath, $fill->getExternalColor());
- }
- if ($fill->inheritsInternalColor()) {
- $modulePath = $modulePath->append($internalPath->translate($xTranslation, $yTranslation));
- } else {
- $this->imageBackEnd->drawPathWithColor($internalPath, $fill->getInternalColor());
- }
- $this->imageBackEnd->pop();
- return $modulePath;
- }
- }
|