Skip to content

Commit f1a12e5

Browse files
authored
Merge pull request #265 from CTSR/master
Reduce the number of SVG rectangles
2 parents 5729529 + c2a8148 commit f1a12e5

File tree

1 file changed

+69
-14
lines changed

1 file changed

+69
-14
lines changed

QRCoder/SvgQRCode.cs

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
#if NETFRAMEWORK || NETSTANDARD2_0
1+
#if NETFRAMEWORK || NETSTANDARD2_0
22
using System;
3+
using System.Collections;
34
using System.Drawing;
45
using System.Text;
56
using static QRCoder.QRCodeGenerator;
@@ -44,22 +45,76 @@ public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool d
4445

4546
public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
4647
{
47-
var offset = drawQuietZones ? 0 : 4;
48-
var drawableModulesCount = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
49-
var pixelsPerModule = (double)Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
50-
var qrSize = drawableModulesCount * pixelsPerModule;
51-
var svgSizeAttributes = (sizingMode == SizingMode.WidthHeightAttribute) ? $@"width=""{viewBox.Width}"" height=""{viewBox.Height}""" : $@"viewBox=""0 0 {viewBox.Width} {viewBox.Height}""";
52-
var svgFile = new StringBuilder($@"<svg version=""1.1"" baseProfile=""full"" shape-rendering=""crispEdges"" {svgSizeAttributes} xmlns=""http://www.w3.org/2000/svg"">");
48+
int offset = drawQuietZones ? 0 : 4;
49+
int drawableModulesCount = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
50+
double pixelsPerModule = Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
51+
double qrSize = drawableModulesCount * pixelsPerModule;
52+
string svgSizeAttributes = (sizingMode == SizingMode.WidthHeightAttribute) ? $@"width=""{viewBox.Width}"" height=""{viewBox.Height}""" : $@"viewBox=""0 0 {viewBox.Width} {viewBox.Height}""";
53+
54+
// Merge horizontal rectangles
55+
int[,] matrix = new int[drawableModulesCount, drawableModulesCount];
56+
for (int yi = 0; yi < drawableModulesCount; yi += 1)
57+
{
58+
BitArray bitArray = this.QrCodeData.ModuleMatrix[yi];
59+
60+
int x0 = -1;
61+
int xL = 0;
62+
for (int xi = 0; xi < drawableModulesCount; xi += 1)
63+
{
64+
matrix[yi, xi] = 0;
65+
if (bitArray[xi])
66+
{
67+
if(x0 == -1)
68+
{
69+
x0 = xi;
70+
}
71+
xL += 1;
72+
}
73+
else
74+
{
75+
if(xL > 0)
76+
{
77+
matrix[yi, x0] = xL;
78+
x0 = -1;
79+
xL = 0;
80+
}
81+
}
82+
}
83+
84+
if (xL > 0)
85+
{
86+
matrix[yi, x0] = xL;
87+
}
88+
}
89+
90+
StringBuilder svgFile = new StringBuilder($@"<svg version=""1.1"" baseProfile=""full"" shape-rendering=""crispEdges"" {svgSizeAttributes} xmlns=""http://www.w3.org/2000/svg"">");
5391
svgFile.AppendLine($@"<rect x=""0"" y=""0"" width=""{CleanSvgVal(qrSize)}"" height=""{CleanSvgVal(qrSize)}"" fill=""{lightColorHex}"" />");
54-
for (int xi = offset; xi < offset + drawableModulesCount; xi++)
92+
for (int yi = 0; yi < drawableModulesCount; yi += 1)
5593
{
56-
for (int yi = offset; yi < offset + drawableModulesCount; yi++)
94+
double y = yi * pixelsPerModule;
95+
for (int xi = 0; xi < drawableModulesCount; xi += 1)
5796
{
58-
if (this.QrCodeData.ModuleMatrix[yi][xi])
97+
int xL = matrix[yi, xi];
98+
if(xL > 0)
5999
{
60-
var x = (xi - offset) * pixelsPerModule;
61-
var y = (yi - offset) * pixelsPerModule;
62-
svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(pixelsPerModule)}"" height=""{CleanSvgVal(pixelsPerModule)}"" fill=""{darkColorHex}"" />");
100+
// Merge vertical rectangles
101+
int yL = 1;
102+
for (int y2 = yi + 1; y2 < drawableModulesCount; y2 += 1)
103+
{
104+
if(matrix[y2, xi] == xL)
105+
{
106+
matrix[y2, xi] = 0;
107+
yL += 1;
108+
}
109+
else
110+
{
111+
break;
112+
}
113+
}
114+
115+
// Output SVG rectangles
116+
double x = xi * pixelsPerModule;
117+
svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(xL * pixelsPerModule)}"" height=""{CleanSvgVal(yL * pixelsPerModule)}"" fill=""{darkColorHex}"" />");
63118
}
64119
}
65120
}
@@ -92,4 +147,4 @@ public static string GetQRCode(string plainText, int pixelsPerModule, string dar
92147
}
93148
}
94149

95-
#endif
150+
#endif

0 commit comments

Comments
 (0)