Skip to content

rounded #317

@stefanoalmonte

Description

@stefanoalmonte

Feature description

this is my code

<?php
require_once 'chillerlan/phpqrcode/vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\Output\{QROutputInterface, QRGdImagePNG, QRCodeOutputException, QRImagick};
use chillerlan\QRCode\Common\EccLevel;

class QRImageWithLogo extends QRGdImagePNG{

    /**
     * @throws \chillerlan\QRCode\Output\QRCodeOutputException
     */
    public function dump(string|null $file = null, string|null $logo = null):string{
        $logo ??= '';

        // 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);

        if($im === false){
            throw new QRCodeOutputException('imagecreatefrompng() error');
        }

        // 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->getSize() * $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();

        $this->saveToFile($imageData, $file);

        if($this->options->outputBase64){
            $imageData = $this->toBase64DataURI($imageData);
        }

        return $imageData;
    }

}

class QRGdRounded extends QRGdImagePNG{

    public function __construct(SettingsContainerInterface|QROptions $options, QRMatrix $matrix){

        // enable the internal scaling for better rounding results at scale < 20
        $options->drawCircularModules = true;

        parent::__construct($options, $matrix);
    }

    protected function module(int $x, int $y, int $M_TYPE):void{

        /**
         * The bit order (starting from 0):
         *
         *   0 1 2
         *   7 # 3
         *   6 5 4
         */
        $neighbours = $this->matrix->checkNeighbours($x, $y);

        $x1         = ($x * $this->scale);
        $y1         = ($y * $this->scale);
        $x2         = (($x + 1) * $this->scale);
        $y2         = (($y + 1) * $this->scale);
        $rectsize   = (int)($this->scale / 2);

        $light      = $this->getModuleValue($M_TYPE);
        $dark       = $this->getModuleValue($M_TYPE | QRMatrix::IS_DARK);

        // ------------------
        // Outer rounding
        // ------------------

        if(($neighbours & (1 << 7))){ // neighbour left
            // top left
            imagefilledrectangle($this->image, $x1, $y1, ($x1 + $rectsize), ($y1 + $rectsize), $light);
            // bottom left
            imagefilledrectangle($this->image, $x1, ($y2 - $rectsize), ($x1 + $rectsize), $y2, $light);
        }

        if(($neighbours & (1 << 3))){ // neighbour right
            // top right
            imagefilledrectangle($this->image, ($x2 - $rectsize), $y1, $x2, ($y1 + $rectsize), $light);
            // bottom right
            imagefilledrectangle($this->image, ($x2 - $rectsize), ($y2 - $rectsize), $x2, $y2, $light);
        }

        if(($neighbours & (1 << 1))){ // neighbour top
            // top left
            imagefilledrectangle($this->image, $x1, $y1, ($x1 + $rectsize), ($y1 + $rectsize), $light);
            // top right
            imagefilledrectangle($this->image, ($x2 - $rectsize), $y1, $x2, ($y1 + $rectsize), $light);
        }

        if(($neighbours & (1 << 5))){ // neighbour bottom
            // bottom left
            imagefilledrectangle($this->image, $x1, ($y2 - $rectsize), ($x1 + $rectsize), $y2, $light);
            // bottom right
            imagefilledrectangle($this->image, ($x2 - $rectsize), ($y2 - $rectsize), $x2, $y2, $light);
        }

        // ---------------------
        // inner rounding
        // ---------------------

        if(!$this->matrix->check($x, $y)){

            if(($neighbours & 1) && ($neighbours & (1 << 7)) && ($neighbours & (1 << 1))){
                // top left
                imagefilledrectangle($this->image, $x1, $y1, ($x1 + $rectsize), ($y1 + $rectsize), $dark);
            }

            if(($neighbours & (1 << 1)) && ($neighbours & (1 << 2)) && ($neighbours & (1 << 3))){
                // top right
                imagefilledrectangle($this->image, ($x2 - $rectsize), $y1, $x2, ($y1 + $rectsize), $dark);
            }

            if(($neighbours & (1 << 7)) && ($neighbours & (1 << 6)) && ($neighbours & (1 << 5))){
                // bottom left
                imagefilledrectangle($this->image, $x1, ($y2 - $rectsize), ($x1 + $rectsize), $y2, $dark);
            }

            if(($neighbours & (1 << 3)) && ($neighbours & (1 << 4)) && ($neighbours & (1 << 5))){
                // bottom right
                imagefilledrectangle($this->image, ($x2 - $rectsize), ($y2 - $rectsize), $x2, $y2, $dark);
            }
        }

        imagefilledellipse(
            $this->image,
            (int)($x * $this->scale + $this->scale / 2),
            (int)($y * $this->scale + $this->scale / 2),
            ($this->scale - 1),
            ($this->scale - 1),
            $light,
        );
    }

}

$options = new QROptions([
    'version'    => 7,
    'eccLevel'   => EccLevel::H,
    'outputInterface' => QRGdRounded::class,
    'outputBase64' => false,
    'addLogoSpace' => true,
    'logoSpaceWidth'  => 8,
    'logoSpaceHeight' => 10,
    'scale' => 8,
    'transparencyColor' => 'transparent',
    'quietzoneSize' => 2,
    'imageTransparent' => true,
    'drawLightModules'    => false,
    'keepAsSquare' => [
        QRMatrix::M_DATA,
        QRMatrix::M_DATA_DARK,
        QRMatrix::M_NULL
    ],
    'moduleValues' => [
    QRMatrix::M_FINDER_DARK    => [109, 185, 108], // dark (true)
    QRMatrix::M_FINDER_DOT     => [109, 185, 108], // finder dot, dark (true)
    QRMatrix::M_ALIGNMENT_DARK => [35,73,152],
    QRMatrix::M_ALIGNMENT      => [35,73,152],

    QRMatrix::M_DATA => [35,73,152],//interno
    QRMatrix::M_DATA_DARK => [35,73,152],//interno
    QRMatrix::M_NULL => [35,73,152],//interno
    QRMatrix::M_FORMAT_DARK => [35,73,152],//interno
    QRMatrix::M_TIMING_DARK => [35,73,152],//interno
    QRMatrix::M_VERSION_DARK => [35,73,152],//interno
    QRMatrix::M_FORMAT => [35,73,152],//interno
    QRMatrix::M_VERSION => [35,73,152],//interno
    QRMatrix::M_SEPARATOR_DARK => [35,73,152],//interno
    QRMatrix::M_DARKMODULE => [35,73,152],//interno

    ]
]);

$qrcode = new QRCode($options);
$mx = $qrcode->getQRMatrix();

$link = (new QRCode($options))->render('https://google.it');

$qrOutputInterface = new QRImageWithLogo($options, $qrcode->getQRMatrix());

// Genera con logo
$out = $qrOutputInterface->dump(null, 'widget-eccoci/pin.png');

header('Content-type: image/png');

//echo $link;
echo $out;
//echo $img;


?>

but rounded not work ...
can help me?
thanks

Code sample

Additional context

No response

Pull Request

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions