Skip to content

Commit f10daa1

Browse files
authored
Merge pull request #351 from codebude/bugfix/291-iconborderwidth-doesnt-work
Bugfix/291 iconborderwidth doesnt work
2 parents c9314f9 + 940798b commit f10daa1

File tree

2 files changed

+121
-43
lines changed

2 files changed

+121
-43
lines changed

QRCoder/QRCode.cs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
5858
return bmp;
5959
}
6060

61-
public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Bitmap icon=null, int iconSizePercent=15, int iconBorderWidth = 6, bool drawQuietZones = true)
61+
public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Bitmap icon=null, int iconSizePercent=15, int iconBorderWidth = 0, bool drawQuietZones = true, Color? iconBackgroundColor = null)
6262
{
6363
var size = (this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8)) * pixelsPerModule;
6464
var offset = drawQuietZones ? 0 : 4 * pixelsPerModule;
@@ -72,36 +72,34 @@ public Bitmap GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor,
7272
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
7373
gfx.CompositingQuality = CompositingQuality.HighQuality;
7474
gfx.Clear(lightColor);
75-
7675
var drawIconFlag = icon != null && iconSizePercent > 0 && iconSizePercent <= 100;
77-
78-
GraphicsPath iconPath = null;
79-
float iconDestWidth = 0, iconDestHeight = 0, iconX = 0, iconY = 0;
80-
81-
if (drawIconFlag)
82-
{
83-
iconDestWidth = iconSizePercent * bmp.Width / 100f;
84-
iconDestHeight = drawIconFlag ? iconDestWidth * icon.Height / icon.Width : 0;
85-
iconX = (bmp.Width - iconDestWidth) / 2;
86-
iconY = (bmp.Height - iconDestHeight) / 2;
87-
88-
var centerDest = new RectangleF(iconX - iconBorderWidth, iconY - iconBorderWidth, iconDestWidth + iconBorderWidth * 2, iconDestHeight + iconBorderWidth * 2);
89-
iconPath = this.CreateRoundedRectanglePath(centerDest, iconBorderWidth * 2);
90-
}
91-
76+
9277
for (var x = 0; x < size + offset; x = x + pixelsPerModule)
9378
{
9479
for (var y = 0; y < size + offset; y = y + pixelsPerModule)
9580
{
9681
var moduleBrush = this.QrCodeData.ModuleMatrix[(y + pixelsPerModule) / pixelsPerModule - 1][(x + pixelsPerModule) / pixelsPerModule - 1] ? darkBrush : lightBrush;
97-
9882
gfx.FillRectangle(moduleBrush , new Rectangle(x - offset, y - offset, pixelsPerModule, pixelsPerModule));
9983
}
10084
}
10185

10286
if (drawIconFlag)
10387
{
88+
float iconDestWidth = iconSizePercent * bmp.Width / 100f;
89+
float iconDestHeight = drawIconFlag ? iconDestWidth * icon.Height / icon.Width : 0;
90+
float iconX = (bmp.Width - iconDestWidth) / 2;
91+
float iconY = (bmp.Height - iconDestHeight) / 2;
92+
var centerDest = new RectangleF(iconX - iconBorderWidth, iconY - iconBorderWidth, iconDestWidth + iconBorderWidth * 2, iconDestHeight + iconBorderWidth * 2);
10493
var iconDestRect = new RectangleF(iconX, iconY, iconDestWidth, iconDestHeight);
94+
var iconBgBrush = iconBackgroundColor != null ? new SolidBrush((Color)iconBackgroundColor) : lightBrush;
95+
//Only render icon/logo background, if iconBorderWith is set > 0
96+
if (iconBorderWidth > 0)
97+
{
98+
using (GraphicsPath iconPath = CreateRoundedRectanglePath(centerDest, iconBorderWidth * 2))
99+
{
100+
gfx.FillPath(iconBgBrush, iconPath);
101+
}
102+
}
105103
gfx.DrawImage(icon, iconDestRect, new RectangleF(0, 0, icon.Width, icon.Height), GraphicsUnit.Pixel);
106104
}
107105

@@ -129,7 +127,7 @@ internal GraphicsPath CreateRoundedRectanglePath(RectangleF rect, int cornerRadi
129127

130128
public static class QRCodeHelper
131129
{
132-
public static Bitmap GetQRCode(string plainText, int pixelsPerModule, Color darkColor, Color lightColor, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1, Bitmap icon = null, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true)
130+
public static Bitmap GetQRCode(string plainText, int pixelsPerModule, Color darkColor, Color lightColor, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1, Bitmap icon = null, int iconSizePercent = 15, int iconBorderWidth = 0, bool drawQuietZones = true)
133131
{
134132
using (var qrGenerator = new QRCodeGenerator())
135133
using (var qrCodeData = qrGenerator.CreateQrCode(plainText, eccLevel, forceUtf8, utf8BOM, eciMode, requestedVersion))

QRCoderTests/QRCodeRendererTests.cs

Lines changed: 104 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class QRCodeRendererTests
1919
#if !NETCOREAPP1_1
2020
[Fact]
2121
[Category("QRRenderer/QRCode")]
22-
public void can_create_standard_qrcode_graphic()
22+
public void can_create_qrcode_standard_graphic()
2323
{
2424
var gen = new QRCodeGenerator();
2525
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
@@ -28,10 +28,36 @@ public void can_create_standard_qrcode_graphic()
2828
var result = HelperFunctions.BitmapToHash(bmp);
2929
result.ShouldBe("e8c61b8f0455924fe08ba68686d0d296");
3030
}
31-
#endif
3231

32+
[Fact]
33+
[Category("QRRenderer/QRCode")]
34+
public void can_create_qrcode_standard_graphic_hex()
35+
{
36+
var gen = new QRCodeGenerator();
37+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
38+
var bmp = new QRCode(data).GetGraphic(10, "#000000", "#ffffff");
39+
40+
var result = HelperFunctions.BitmapToHash(bmp);
41+
result.ShouldBe("e8c61b8f0455924fe08ba68686d0d296");
42+
}
43+
44+
45+
[Fact]
46+
[Category("QRRenderer/QRCode")]
47+
public void can_create_qrcode_standard_graphic_without_quietzones()
48+
{
49+
var gen = new QRCodeGenerator();
50+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
51+
var bmp = new QRCode(data).GetGraphic(5, Color.Black, Color.White, false);
52+
53+
var result = HelperFunctions.BitmapToHash(bmp);
54+
#if NET35_OR_GREATER || NET40_OR_GREATER
55+
result.ShouldBe("329e1664f57cbe7332d8d4db04c1d480");
56+
#else
57+
result.ShouldBe("d703e54a0ba541c6ea69e3d316e394e7");
58+
#endif
59+
}
3360

34-
#if !NETCOREAPP1_1 && !NETCOREAPP2_0
3561

3662
[Fact]
3763
[Category("QRRenderer/QRCode")]
@@ -43,7 +69,6 @@ public void can_create_qrcode_with_transparent_logo_graphic()
4369

4470
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
4571
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
46-
4772
var result = HelperFunctions.BitmapToHash(bmp);
4873
#if NET35_OR_GREATER || NET40_OR_GREATER
4974
result.ShouldBe("ee65d96c3013f6032b561cc768251eef");
@@ -70,28 +95,83 @@ public void can_create_qrcode_with_non_transparent_logo_graphic()
7095
#endif
7196
}
7297

73-
/*
74-
private static byte[] PixelsToAveragedByteArray(Bitmap bmp)
98+
[Fact]
99+
[Category("QRRenderer/QRCode")]
100+
public void can_create_qrcode_with_logo_and_with_transparent_border()
101+
{
102+
//Create QR code
103+
var gen = new QRCodeGenerator();
104+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
105+
106+
var logo = (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png");
107+
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: logo, iconBorderWidth: 6);
108+
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
109+
var result = HelperFunctions.BitmapToHash(bmp);
110+
#if NET35_OR_GREATER || NET40_OR_GREATER
111+
result.ShouldBe("ee65d96c3013f6032b561cc768251eef");
112+
#else
113+
result.ShouldBe("150f8fc7dae4487ba2887d2b2bea1c25");
114+
#endif
115+
}
116+
117+
[Fact]
118+
[Category("QRRenderer/QRCode")]
119+
public void can_create_qrcode_with_logo_and_with_standard_border()
120+
{
121+
//Create QR code
122+
var gen = new QRCodeGenerator();
123+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
124+
125+
var logo = (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png");
126+
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.White, icon: logo, iconBorderWidth: 6);
127+
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
128+
var result = HelperFunctions.BitmapToHash(bmp);
129+
#if NET35_OR_GREATER || NET40_OR_GREATER
130+
result.ShouldBe("52207bd86ca5a532fb2095dbaa0ae04c");
131+
#else
132+
result.ShouldBe("1c926ea1d48f42fdf8e6f1438b774cdd");
133+
#endif
134+
}
135+
136+
[Fact]
137+
[Category("QRRenderer/QRCode")]
138+
public void can_create_qrcode_with_logo_and_with_custom_border()
75139
{
76-
//Re-color
77-
var bmpTmp = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
78-
using (var gr = Graphics.FromImage(bmp))
79-
gr.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
80-
81-
//Downscale
82-
var bmpSmall = new Bitmap(bmpTmp, new Size(16, 16));
83-
84-
var bytes = new System.Collections.Generic.List<byte>();
85-
for (int x = 0; x < bmpSmall.Width; x++)
86-
{
87-
for (int y = 0; y < bmpSmall.Height; y++)
88-
{
89-
bytes.AddRange(new byte[] { bmpSmall.GetPixel(x, y).R, bmpSmall.GetPixel(x, y).G, bmpSmall.GetPixel(x, y).B });
90-
}
91-
}
92-
return bytes.ToArray();
140+
//Create QR code
141+
var gen = new QRCodeGenerator();
142+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
143+
144+
var logo = (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png");
145+
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: logo, iconBorderWidth: 6, iconBackgroundColor: Color.DarkGreen);
146+
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
147+
var result = HelperFunctions.BitmapToHash(bmp);
148+
#if NET35_OR_GREATER || NET40_OR_GREATER
149+
result.ShouldBe("d2f20d34a973d92b9c3e05db1393b331");
150+
#else
151+
result.ShouldBe("9a06bfbb72df999b6290b5af5c4037cb");
152+
#endif
153+
}
154+
155+
156+
[Fact]
157+
[Category("QRRenderer/QRCode")]
158+
public void can_instantate_qrcode_parameterless()
159+
{
160+
var svgCode = new QRCode();
161+
svgCode.ShouldNotBeNull();
162+
svgCode.ShouldBeOfType<QRCode>();
163+
}
164+
165+
[Fact]
166+
[Category("QRRenderer/QRCode")]
167+
public void can_render_qrcode_from_helper()
168+
{
169+
//Create QR code
170+
var bmp = QRCodeHelper.GetQRCode("This is a quick test! 123#?", 10, Color.Black, Color.White, QRCodeGenerator.ECCLevel.H);
171+
172+
var result = HelperFunctions.BitmapToHash(bmp);
173+
result.ShouldBe("e8c61b8f0455924fe08ba68686d0d296");
93174
}
94-
*/
95175
#endif
96176
}
97177
}

0 commit comments

Comments
 (0)