Open maxpelic opened 3 years ago
Not that anyone cares but I got it even more compressed...
public function printSVG($size = 2)
{
$width = $this->getModuleCount() * $size;
$height = $width;
print('<svg width="' . $width . '" height="' . $height . '" viewbox="0 0 ' . $this->getModuleCount() . ' ' . $this->getModuleCount() . '" xmlns="http://www.w3.org/2000/svg"><path d="');
for ($r = 0; $r < $this->getModuleCount(); $r++) {
print('M0 ' . $r);
$mx = $wtrack = 0;
for ($c = 0; $c < $this->getModuleCount(); $c++) {
if($this->isDark($r, $c)){
$wtrack++;
continue;
}
if(!$wtrack){
$mx++;
continue;
}
print('h' . ($mx) . "v1h" . ($wtrack) . "v-1");
$mx = 1;
$wtrack = 0;
}
if($wtrack){
print('h' . ($mx) . "v1h" . ($wtrack) . "v-1");
$wtrack = 0;
}
print('z');
}
print("\"></path></svg>");
}
In case someone cares... SVG-output can be compressed still more to about 15 times smaller than the 'official version' of printSVG. Just draw horizontal lines $size pixels wide - avoiding all filled rectangles! - and leave-out all defaults and unnecessary spaces. This function has additional parameters (title and colors to support transparency, margin, border) and returns a html svg-tag which can subsequently be echoed, printed or stored in a db, etc. Also included a few efficiency improvements (reducing number of computations inside loops).
public function createSVG($title='', $size=2, $color='black/white') {
$size = max(2, $size);
// $color usage: fgc OR fgc/bgc OR fgc/bgc/brdc
list($fgc, $bgc, $brdc) = array_pad(explode('/',$color), 3, '');
$margin = ($brdc ? $size+1 : 0); // if border(-color) add margin
$n = $this->getModuleCount();
$svgSize = $n * $size + 2 * $margin; // square; default: viewBox 0 0 $svgSize $svgSize
$svgOut = "<svg width=$svgSize height=$svgSize xmlns='http://www.w3.org/2000/svg'>";
if ($title) $svgOut .= "<title>$title</title>";
// no bgc = 'transparent' background, no brdc = no border
if ($bgc || $brdc) { // background or border color
if (!$bgc) $bgc = 'transparent';
$attr = "fill='$bgc'" . ($brdc ? " stroke='$brdc' stroke-width=1" : '');
$svgOut .= "<rect x=0 y=0 width=$svgSize height=$svgSize $attr />";
}
// use path to draw hor.line sections; default: stroke-linecap="butt"
$svgOut .= "<path fill='none' stroke='$fgc' stroke-width=$size d='";
for ($r = 0; $r < $n; $r++) {
$y = (int)floor(($r + 0.5) * $size) + $margin; // half-way rows!
$svgOut .= "M$margin $y"; // newline (abs.move)
$currX = $lastX = $margin;
for ($c = 0; $c < $n; $c++) {
$new = $this->isDark($r,$c);
if ($c==0) $curr = $new; // first cell
elseif ($new!==$curr) { // dark <-> notDark
$x = $currX - $lastX; // relative distance
if ($curr) $svgOut .= "h$x"; // draw horz.
else $svgOut .= "m$x 0"; // move horz.
$curr = $new;
$lastX = $currX;
}
$currX += $size;
}
if ($curr) { // last cell
$x = $currX - $lastX;
$svgOut .= "h$x"; // draw until eol
}
}
$svgOut .= "'/></svg>";
return $svgOut;
}
NB. a 2-color PNG is still the smallest QRcode to publish
Damn! You guys did a great work. @maxpelic @RIMhosting Would be great if it had been included.
The QR code generator function does not compress the data at all, changing it to something like
makes the output data waaaaay smaller while still printing the same thing (it has a transparent background but that could easily be changed by just adding a white rect first).