QR SVG RENDER with Hearts #150
Replies: 5 comments 12 replies
-
Hey, yes, this would be possible with the SVG output module (dev-main, upcoming v5). The second example is possible with very few modifications - you would need to extend the protected function module(int $x, int $y, int $M_TYPE):string{
if(!$this->options->drawLightModules && !$this->matrix->check($x, $y)){
return '';
}
// modify the output of circular modules to return hearts instead
// you can then use the respective option values to modify the behaviour
if($this->options->drawCircularModules && $this->matrix->checkTypeNotIn($x, $y, $this->options->keepAsSquare)){
return sprintf('M%1$s %2$s m0.5,0.96 l-0.412,-0.412 a0.3 0.3 0 0 1 0.412,-0.435 a0.3 0.3 0 0 1 0.412,0.435Z', $x, $y);
}
return sprintf('M%1$s %2$s h1 v1 h-1Z', $x, $y);
} If you want to keep the circular modules, you'd need to add your own option values of course - you can find an example for that over here. The path segment starts at the position of the module ($x, $y - top left corner) and is drawn with relative coordinates from there. You can find an example of shapes and positioning in this SVG image. The first example is a bit more complex but can be solved by checking for the Unfortunately it's not easy to convert an SVG image to a raster format in PHP with Imagick without losses, so you would instead need to call the Inkscape command line tool. |
Beta Was this translation helpful? Give feedback.
-
So i made a quick example of how to modify the finder patterns and use custom shapes for them. As i mentioned before, there are several ways of achieving this. class QRSvgWithLogoAndCustomShapes extends QRMarkupSVG{
/**
* @inheritDoc
*/
protected function paths():string{
// make sure connect paths is enabled
$this->options->connectPaths = true;
// empty the default value to remove the fill* attributes from the <path> elements
$this->options->markupDark = '';
$this->options->markupLight = '';
$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);
// generate the path element(s) - in this case it's just one element as we've "disabled" several options
$svg = parent::paths();
// now we're lazy modifying the generated path to add the custom shapes for the finder patterns
$svg = str_replace('"/>', $this->getFinderPatterns().'"/>', $svg);
// and add the custom logo
$svg .= $this->getLogo();
return $svg;
}
/**
* returns a path segment for a single module
*
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
*/
protected function module(int $x, int $y, int $M_TYPE):string{
if(
!$this->matrix->check($x, $y)
// we're skipping the finder patterns here
|| $this->matrix->checkType($x, $y, QRMatrix::M_FINDER)
|| $this->matrix->checkType($x, $y, QRMatrix::M_FINDER_DOT)
){
return '';
}
// return a heart shape (or any custom shape for that matter)
return sprintf('M%1$s %2$s m0.5,0.96 l-0.412,-0.412 a0.3 0.3 0 0 1 0.412,-0.435 a0.3 0.3 0 0 1 0.412,0.435Z', $x, $y);
}
/**
* returns a custom path for the 3 finder patterns
*/
protected function getFinderPatterns():string{
$qz = $this->options->addQuietzone ? $this->options->quietzoneSize : 0;
// the positions for the finder patterns (top left corner)
// $this->moduleCount includes 2* the quiet zone size already so we need to take this into account
$pos = [
[0 + $qz, 0 + $qz],
[0 + $qz, $this->moduleCount - $qz - 7],
[$this->moduleCount - $qz - 7, 0 + $qz],
];
// the custom path for one finder pattern - the first move (M) is parametrized, the rest are relative coordinates
$path = 'M%1$s,%2$s m2,0 h3 q2,0 2,2 v3 q0,2 -2,2 h-3 q-2,0 -2,-2 v-3 q0,-2 2,-2z m0,1 q-1,0 -1,1 v3 q0,1 1,1 h3 q1,0 1,-1 v-3 q0,-1 -1,-1z m0,2.5 a1.5,1.5 0 1 0 3,0 a1.5,1.5 0 1 0 -3,0Z';
$finder = [];
foreach($pos as $coord){
[$ix, $iy] = $coord;
$finder[] = sprintf($path, $ix, $iy);
}
return implode(' ', $finder);
}
/**
* 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
);
}
} |
Beta Was this translation helpful? Give feedback.
-
I was playing around a bit with this example. I'd like to have the Finder markers more rounded like this, but inside not a circle. How do you create such a simple path? I make an SVG with a rounded square marker in the middle.
However, I can't find a way to change the path back to the example like: I get that If you can help me with this, that would be great. By the way for people reading this too. I didn't wanted the hearts so I changed it back to the circle:
|
Beta Was this translation helpful? Give feedback.
-
it's once again me! is there a possibility to define the SIZE of the created QR Code which is generated as PNG in PX e.g. 2000x2000px? |
Beta Was this translation helpful? Give feedback.
-
Hello im not able to put logo center of it can you help and also the hearth shape is not working too |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi! I wanted to check with the group and see if this would be also beneficial to any of them.
1.) We want to use Chillerlan solution to create a beautiful QR code looking like this:
2.) in a second step the QR Code should be combined to a existing SVG or PNG with exact coordinates..
Is there a possibility to do this with Chillerlan? And how is the right way to achieve this?
Thanks a lot for Help!
BR Mike
Beta Was this translation helpful? Give feedback.
All reactions