Skip to content

Commit 0c3bc02

Browse files
authored
Merge pull request #344 from codebude/feature/art-qrcode-refactoring
Feature/art qrcode refactoring
2 parents 942cd35 + f8d9c83 commit 0c3bc02

10 files changed

+361
-93
lines changed

QRCoder/ArtQRCode.cs

Lines changed: 153 additions & 37 deletions
Large diffs are not rendered by default.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#if !NETCOREAPP1_1
2+
3+
using Xunit;
4+
using QRCoder;
5+
using Shouldly;
6+
using System.Drawing;
7+
using QRCoderTests.Helpers.XUnitExtenstions;
8+
using QRCoderTests.Helpers;
9+
10+
namespace QRCoderTests
11+
{
12+
13+
public class ArtQRCodeRendererTests
14+
{
15+
16+
17+
[Fact]
18+
[Category("QRRenderer/ArtQRCode")]
19+
public void can_create_standard_qrcode_graphic()
20+
{
21+
var gen = new QRCodeGenerator();
22+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
23+
var bmp = new ArtQRCode(data).GetGraphic(10);
24+
25+
var result = HelperFunctions.BitmapToHash(bmp);
26+
#if NET35_OR_GREATER || NET40_OR_GREATER
27+
result.ShouldBe("11ebdda91b9632d016798cb6de2f5339");
28+
#else
29+
result.ShouldBe("cb38c3156eaf13cdfba699bdafc3a84c");
30+
#endif
31+
}
32+
33+
[Fact]
34+
[Category("QRRenderer/ArtQRCode")]
35+
public void can_create_standard_qrcode_graphic_with_custom_finder()
36+
{
37+
var gen = new QRCodeGenerator();
38+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
39+
var finder = new Bitmap(15, 15);
40+
var bmp = new ArtQRCode(data).GetGraphic(10, Color.Black, Color.White, Color.Transparent, finderPatternImage: finder);
41+
42+
var result = HelperFunctions.BitmapToHash(bmp);
43+
#if NET35_OR_GREATER || NET40_OR_GREATER
44+
result.ShouldBe("c54a7389ae995abc838f0d228acc3bad");
45+
#else
46+
result.ShouldBe("1102c0c6f235eaf4c3ac639f82f17bfa");
47+
#endif
48+
}
49+
50+
[Fact]
51+
[Category("QRRenderer/ArtQRCode")]
52+
public void can_create_standard_qrcode_graphic_without_quietzone()
53+
{
54+
var gen = new QRCodeGenerator();
55+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
56+
var bmp = new ArtQRCode(data).GetGraphic(10, Color.Black, Color.White, Color.Transparent, drawQuietZones: false);
57+
58+
var result = HelperFunctions.BitmapToHash(bmp);
59+
#if NET35_OR_GREATER || NET40_OR_GREATER
60+
result.ShouldBe("550f31b988ff12d5f8429ef19d9d5a0c");
61+
#else
62+
result.ShouldBe("632315c8695416fc82fe06a202688433");
63+
#endif
64+
}
65+
66+
[Fact]
67+
[Category("QRRenderer/ArtQRCode")]
68+
public void can_create_standard_qrcode_graphic_with_background()
69+
{
70+
var gen = new QRCodeGenerator();
71+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
72+
var bmp = new ArtQRCode(data).GetGraphic((Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
73+
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
74+
75+
var result = HelperFunctions.BitmapToHash(bmp);
76+
77+
#if NET35_OR_GREATER || NET40_OR_GREATER
78+
result.ShouldBe("2caa9c0ee8fcb4a93841debb58cf41bc");
79+
#else
80+
result.ShouldBe("bbea08507282773175cfe7b52f0ddae4");
81+
#endif
82+
}
83+
84+
[Fact]
85+
[Category("QRRenderer/ArtQRCode")]
86+
public void should_throw_pixelfactor_oor_exception()
87+
{
88+
var gen = new QRCodeGenerator();
89+
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
90+
var aCode = new ArtQRCode(data);
91+
92+
var exception = Record.Exception(() => aCode.GetGraphic(10, Color.Black, Color.White, Color.Transparent, pixelSizeFactor: 2));
93+
Assert.NotNull(exception);
94+
Assert.IsType<System.Exception>(exception);
95+
exception.Message.ShouldBe("The parameter pixelSize must be between 0 and 1. (0-100%)");
96+
}
97+
98+
[Fact]
99+
[Category("QRRenderer/ArtQRCode")]
100+
public void can_instantate_parameterless()
101+
{
102+
var asciiCode = new ArtQRCode();
103+
asciiCode.ShouldNotBeNull();
104+
asciiCode.ShouldBeOfType<ArtQRCode>();
105+
}
106+
107+
[Fact]
108+
[Category("QRRenderer/ArtQRCode")]
109+
public void can_render_artqrcode_from_helper()
110+
{
111+
//Create QR code
112+
var bmp = ArtQRCodeHelper.GetQRCode("A", 10, Color.Black, Color.White, Color.Transparent, QRCodeGenerator.ECCLevel.L);
113+
114+
var result = HelperFunctions.BitmapToHash(bmp);
115+
#if NET35_OR_GREATER || NET40_OR_GREATER
116+
result.ShouldBe("fea51114bc4ff893542a1c0574c82a07");
117+
#else
118+
result.ShouldBe("57ecaa9bdeadcdcbeac8a19d734907ff");
119+
#endif
120+
}
121+
}
122+
}
123+
#endif

QRCoderTests/AsciiQRCodeRendererTests.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Xunit;
22
using QRCoder;
33
using Shouldly;
4-
using QRCoderTests.XUnitExtenstions;
4+
using QRCoderTests.Helpers.XUnitExtenstions;
55

66

77
namespace QRCoderTests
@@ -67,9 +67,7 @@ public void can_render_ascii_qrcode_from_helper()
6767
{
6868
var targetCode = " \n \n \n \n \n \n \n \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XXXX XXXXXXXXXXXXXX \n XX XX XXXXXX XX XX XX \n XX XX XXXXXX XX XX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXXXXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XXXX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XXXXXX XX XX XX XX XXXXXX XX \n XX XX XX XX XX \n XX XX XX XX XX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXXXXXXXX XX XX XX XXXXXXXXXXXXXX \n XXXXXXXX \n XXXXXXXX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXXXX XX XX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XXXXXX XXXX XXXXXXXX XXXXXX XX \n XX XX XX XX XX XX \n XX XX XX XX XX XX \n XX XX XX XX XXXXXX \n XX XX XX XX XXXXXX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX XX XXXXXXXX XX \n XX XXXXXXXX XXXX \n XX XXXXXXXX XXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XXXXXXXXXXXXXX XXXXXXXX XX XXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XX XXXXXX XXXXXXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XX XXXX XX XXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XXXX XXXXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XXXXXX XX XX XXXXXXXX XX XXXXXX \n XX XX XX XXXX XX \n XX XX XX XXXX XX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n XXXXXXXXXXXXXX XX XXXXXX XXXX XXXX \n \n \n \n \n \n \n \n ";
6969

70-
//Create QR code
71-
var gen = new QRCodeGenerator();
72-
var data = gen.CreateQrCode("A", QRCodeGenerator.ECCLevel.Q);
70+
//Create QR code
7371
var asciiCode = AsciiQRCodeHelper.GetQRCode("A", 2, "X", " ", QRCodeGenerator.ECCLevel.Q);
7472
asciiCode.ShouldBe(targetCode);
7573
}

QRCoderTests/CategoryDiscoverer.cs renamed to QRCoderTests/Helpers/CategoryDiscoverer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#endif
77
using Xunit.Sdk;
88

9-
namespace QRCoderTests.XUnitExtenstions
9+
namespace QRCoderTests.Helpers.XUnitExtenstions
1010
{
1111
#if NET35 || NET452
1212
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.IO;
6+
using System.Security.Cryptography;
7+
#if !NETCOREAPP1_1
8+
using System.Drawing;
9+
#endif
10+
11+
namespace QRCoderTests.Helpers
12+
{
13+
public static class HelperFunctions
14+
{
15+
16+
#if !NETCOREAPP1_1
17+
public static string GetAssemblyPath()
18+
{
19+
return
20+
#if NET5_0
21+
AppDomain.CurrentDomain.BaseDirectory;
22+
#else
23+
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\", "");
24+
#endif
25+
}
26+
#endif
27+
28+
29+
#if !NETCOREAPP1_1
30+
public static string BitmapToHash(Bitmap bmp)
31+
{
32+
byte[] imgBytes = null;
33+
using (var ms = new MemoryStream())
34+
{
35+
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
36+
imgBytes = ms.ToArray();
37+
ms.Dispose();
38+
}
39+
var md5 = new MD5CryptoServiceProvider();
40+
var hash = md5.ComputeHash(imgBytes);
41+
return BitConverter.ToString(hash).Replace("-", "").ToLower();
42+
}
43+
#endif
44+
45+
}
46+
}

QRCoderTests/PayloadGeneratorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using Shouldly;
55
using System.Globalization;
66
using System.Threading;
7-
using QRCoderTests.XUnitExtenstions;
7+
using QRCoderTests.Helpers.XUnitExtenstions;
88
using static QRCoder.PayloadGenerator.BezahlCode;
99
using static QRCoder.PayloadGenerator.SwissQrCode.Reference;
1010
using System.Reflection;

QRCoderTests/QRCodeRendererTests.cs

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
using Xunit;
33
using QRCoder;
44
using Shouldly;
5-
using QRCoderTests.XUnitExtenstions;
65
using System.IO;
76
using System.Security.Cryptography;
7+
using QRCoderTests.Helpers.XUnitExtenstions;
8+
using QRCoderTests.Helpers;
89
#if !NETCOREAPP1_1
910
using System.Drawing;
1011
#endif
@@ -24,31 +25,14 @@ public void can_create_standard_qrcode_graphic()
2425
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
2526
var bmp = new QRCode(data).GetGraphic(10);
2627

27-
var ms = new MemoryStream();
28-
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
29-
var imgBytes = ms.ToArray();
30-
var md5 = new MD5CryptoServiceProvider();
31-
var hash = md5.ComputeHash(imgBytes);
32-
var result = BitConverter.ToString(hash).Replace("-", "").ToLower();
33-
ms.Dispose();
34-
35-
result.ShouldBe("a76c8a72e95df3368717663c6be41b3e");
28+
var result = HelperFunctions.BitmapToHash(bmp);
29+
result.ShouldBe("e8c61b8f0455924fe08ba68686d0d296");
3630
}
3731
#endif
3832

3933

4034
#if !NETCOREAPP1_1 && !NETCOREAPP2_0
4135

42-
private string GetAssemblyPath()
43-
{
44-
return
45-
#if NET5_0
46-
AppDomain.CurrentDomain.BaseDirectory;
47-
#else
48-
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\", "");
49-
#endif
50-
}
51-
5236
[Fact]
5337
[Category("QRRenderer/QRCode")]
5438
public void can_create_qrcode_with_transparent_logo_graphic()
@@ -57,15 +41,15 @@ public void can_create_qrcode_with_transparent_logo_graphic()
5741
var gen = new QRCodeGenerator();
5842
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
5943

60-
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: (Bitmap)Image.FromFile(GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
44+
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.Transparent, icon: (Bitmap)Image.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
6145
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
6246

63-
var imgBytes = PixelsToAveragedByteArray(bmp);
64-
var md5 = new MD5CryptoServiceProvider();
65-
var hash = md5.ComputeHash(imgBytes);
66-
var result = BitConverter.ToString(hash).Replace("-", "").ToLower();
67-
68-
result.ShouldBe("33c250bf306b7cbbd3dd71b6029b8784");
47+
var result = HelperFunctions.BitmapToHash(bmp);
48+
#if NET35_OR_GREATER || NET40_OR_GREATER
49+
result.ShouldBe("ee65d96c3013f6032b561cc768251eef");
50+
#else
51+
result.ShouldBe("150f8fc7dae4487ba2887d2b2bea1c25");
52+
#endif
6953
}
7054

7155
[Fact]
@@ -75,18 +59,18 @@ public void can_create_qrcode_with_non_transparent_logo_graphic()
7559
//Create QR code
7660
var gen = new QRCodeGenerator();
7761
var data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.H);
78-
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.White, icon: (Bitmap)Bitmap.FromFile(GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
62+
var bmp = new QRCode(data).GetGraphic(10, Color.Black, Color.White, icon: (Bitmap)Bitmap.FromFile(HelperFunctions.GetAssemblyPath() + "\\assets\\noun_software engineer_2909346.png"));
7963
//Used logo is licensed under public domain. Ref.: https://thenounproject.com/Iconathon1/collection/redefining-women/?i=2909346
8064

81-
var imgBytes = PixelsToAveragedByteArray(bmp);
82-
var md5 = new MD5CryptoServiceProvider();
83-
var hash = md5.ComputeHash(imgBytes);
84-
var result = BitConverter.ToString(hash).Replace("-", "").ToLower();
85-
86-
result.ShouldBe("33c250bf306b7cbbd3dd71b6029b8784");
65+
var result = HelperFunctions.BitmapToHash(bmp);
66+
#if NET35_OR_GREATER || NET40_OR_GREATER
67+
result.ShouldBe("1d718f06f904af4a46748f02af2d4eec");
68+
#else
69+
result.ShouldBe("c46a7ec51bf978d7a882059c322ca69d");
70+
#endif
8771
}
8872

89-
73+
/*
9074
private static byte[] PixelsToAveragedByteArray(Bitmap bmp)
9175
{
9276
//Re-color
@@ -107,7 +91,7 @@ private static byte[] PixelsToAveragedByteArray(Bitmap bmp)
10791
}
10892
return bytes.ToArray();
10993
}
110-
94+
*/
11195
#endif
11296
}
11397
}

QRCoderTests/QRGeneratorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using QRCoder;
2-
using QRCoderTests.XUnitExtenstions;
2+
using QRCoderTests.Helpers.XUnitExtenstions;
33
using Shouldly;
44
using System.Collections.Generic;
55
using System.Reflection;

QRCoderTests/SvgQRCodeRendererTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using Xunit;
33
using QRCoder;
44
using Shouldly;
5-
using QRCoderTests.XUnitExtenstions;
5+
using QRCoderTests.Helpers.XUnitExtenstions;
66
using System.IO;
77
using System.Security.Cryptography;
88
#if !NETCOREAPP1_1

readme.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,19 @@ There are a plenty of other options. So feel free to read more on that in our wi
7373

7474
Besides the normal QRCode class (which is shown in the example above) for creating QR codes in Bitmap format, there are some more QR code rendering classes, each for another special purpose.
7575

76-
* [QRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#21-qrcode-renderer-in-detail)
77-
* [AsciiQRCode<sup></sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#22-asciiqrcode-renderer-in-detail)
78-
* [Base64QRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#23-base64qrcode-renderer-in-detail)
79-
* [BitmapByteQRCode<sup></sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#24-bitmapbyteqrcode-renderer-in-detail)
80-
* [PdfByteQRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#210-pdfbyteqrcode-renderer-in-detail)
81-
* [PngByteQRCode<sup></sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#25-pngbyteqrcode-renderer-in-detail)
82-
* [PostscriptQRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#29-postscriptqrcode-renderer-in-detail)
83-
* [SvgQRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#26-svgqrcode-renderer-in-detail)
84-
* [UnityQRCode<sup>**</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#27-unityqrcode-renderer-in-detail)
85-
* [XamlQRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#28-xamlqrcode-renderer-in-detail)
86-
87-
*(&ast;) - These classes are only available in the .NET Framework/.NET Standard version. If you use the PCL version (e.g. for Universal apps), you have to use either BitmapByteQRCode or PngByteQRCode classes.*
76+
* [QRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#21-qrcode-renderer-in-detail)
77+
* [ArtQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#211-artqrcode-renderer-in-detail)
78+
* [AsciiQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#22-asciiqrcode-renderer-in-detail)
79+
* [Base64QRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#23-base64qrcode-renderer-in-detail)
80+
* [BitmapByteQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#24-bitmapbyteqrcode-renderer-in-detail)
81+
* [PdfByteQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#210-pdfbyteqrcode-renderer-in-detail)
82+
* [PngByteQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#25-pngbyteqrcode-renderer-in-detail)
83+
* [PostscriptQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#29-postscriptqrcode-renderer-in-detail)
84+
* [SvgQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#26-svgqrcode-renderer-in-detail)
85+
* [UnityQRCode<sup>*</sup>](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#27-unityqrcode-renderer-in-detail)
86+
* [XamlQRCode](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#28-xamlqrcode-renderer-in-detail)
87+
88+
*Note: Please be aware that not all renderers are available on all target frameworks. Please check the [compatibility table](https://github.com/codebude/QRCoder/wiki/Advanced-usage---QR-Code-renderers#2-overview-of-the-different-renderers) in our wiki, to see if a specific renderer is available on your favourite target framework.*
8889
*(&ast;&ast;) - This class is hosted in an own package ([QRCoder.Unity](https://github.com/codebude/QRCoder.Unity)).*
8990

9091

0 commit comments

Comments
 (0)