Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Base64QRCode on .NET6+ on Linux #495

Merged
merged 10 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 55 additions & 16 deletions QRCoder/Base64QRCode.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS
#if !NETSTANDARD1_3
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using static QRCoder.Base64QRCode;
using static QRCoder.QRCodeGenerator;

namespace QRCoder
{
#if NET6_0_WINDOWS
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
public class Base64QRCode : AbstractQRCode, IDisposable
{
private QRCode qr;

/// <summary>
/// Constructor without params to be used in COM Objects connections
/// </summary>
public Base64QRCode() {
qr = new QRCode();
}

public Base64QRCode(QRCodeData data) : base(data) {
qr = new QRCode(data);
}

public override void SetQRCodeData(QRCodeData data) {
codebude marked this conversation as resolved.
Show resolved Hide resolved
this.qr.SetQRCodeData(data);
}

public string GetGraphic(int pixelsPerModule)
Expand All @@ -43,63 +33,112 @@

public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
if (imgType == ImageType.Png)
{
var pngCoder = new PngByteQRCode(QrCodeData);

byte[] pngData;
if (darkColor == Color.Black && lightColor == Color.White)
{
pngData = pngCoder.GetGraphic(pixelsPerModule, drawQuietZones);
}
else
{
byte[] darkColorBytes;
byte[] lightColorBytes;
if (darkColor.A != 255 || lightColor.A != 255)
codebude marked this conversation as resolved.
Show resolved Hide resolved
{
darkColorBytes = new byte[] { darkColor.R, darkColor.G, darkColor.B, darkColor.A };
lightColorBytes = new byte[] { lightColor.R, lightColor.G, lightColor.B, lightColor.A };
}
else
{
darkColorBytes = new byte[] { darkColor.R, darkColor.G, darkColor.B };
lightColorBytes = new byte[] { lightColor.R, lightColor.G, lightColor.B };
}
pngData = pngCoder.GetGraphic(pixelsPerModule, darkColorBytes, lightColorBytes, drawQuietZones);
}

return Convert.ToBase64String(pngData, Base64FormattingOptions.None);
}

#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS
#pragma warning disable CA1416 // Validate platform compatibility
var qr = new QRCode(QrCodeData);
var base64 = string.Empty;
using (Bitmap bmp = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones))
{
base64 = BitmapToBase64(bmp, imgType);
}
return base64;
#pragma warning restore CA1416 // Validate platform compatibility
#else
throw new PlatformNotSupportedException("Only the PNG image type is supported on this platform.");
#endif
}

#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Bitmap icon, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
var qr = new QRCode(QrCodeData);

Check warning on line 86 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'QRCode' is only supported on: 'windows'.
var base64 = string.Empty;
using (Bitmap bmp = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, icon, iconSizePercent, iconBorderWidth, drawQuietZones))

Check warning on line 88 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'QRCode.GetGraphic(int, Color, Color, Bitmap, int, int, bool, Color?)' is only supported on: 'windows'.
{
base64 = BitmapToBase64(bmp, imgType);
}
return base64;
}
#endif


#if NETFRAMEWORK || NETSTANDARD2_0 || NET5_0 || NET6_0_WINDOWS
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
private string BitmapToBase64(Bitmap bmp, ImageType imgType)
{
var base64 = string.Empty;
ImageFormat iFormat;
switch (imgType) {
case ImageType.Png:
iFormat = ImageFormat.Png;

Check warning on line 106 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'ImageFormat.Png' is only supported on: 'windows'.
break;
case ImageType.Jpeg:
iFormat = ImageFormat.Jpeg;

Check warning on line 109 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'ImageFormat.Jpeg' is only supported on: 'windows'.
break;
case ImageType.Gif:
iFormat = ImageFormat.Gif;

Check warning on line 112 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'ImageFormat.Gif' is only supported on: 'windows'.
break;
default:
iFormat = ImageFormat.Png;

Check warning on line 115 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'ImageFormat.Png' is only supported on: 'windows'.
break;
}
using (MemoryStream memoryStream = new MemoryStream())
{
bmp.Save(memoryStream, iFormat);

Check warning on line 120 in QRCoder/Base64QRCode.cs

View workflow job for this annotation

GitHub Actions / build

This call site is reachable on all platforms. 'Image.Save(Stream, ImageFormat)' is only supported on: 'windows'.
base64 = Convert.ToBase64String(memoryStream.ToArray(), Base64FormattingOptions.None);
}
return base64;
}
#endif

public enum ImageType
{
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
Gif,
#if NET6_0_OR_GREATER
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
Jpeg,
Png
}

}

#if NET6_0_WINDOWS
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
#endif
public static class Base64QRCodeHelper
{
public static string GetQRCode(string plainText, int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false, EciMode eciMode = EciMode.Default, int requestedVersion = -1, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
Expand Down
2 changes: 1 addition & 1 deletion QRCoder/QRCoder.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFrameworks>net35;net40;netstandard1.3;netstandard2.0;net5.0;net5.0-windows;net6.0;net6.0-windows</TargetFrameworks>
codebude marked this conversation as resolved.
Show resolved Hide resolved
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<DefineConstants Condition="'$(TargetFramework)' == 'net5.0-windows'">$(DefineConstants);NET5_0_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' == 'net6.0-windows'">$(DefineConstants);NET6_0_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' == 'net6.0-windows'">$(DefineConstants);NET6_0_WINDOWS</DefineConstants>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
</PropertyGroup>
Expand Down
77 changes: 77 additions & 0 deletions QRCoderTests/Base64QRCodeRendererTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#if !NETCOREAPP1_1
using QRCoder;
using QRCoderTests.Helpers.XUnitExtenstions;
using Shouldly;
using System;
using System.Drawing;
using System.IO;
using Xunit;

namespace QRCoderTests
{
public class Base64QRCodeRendererTests
{
private readonly QRCodeData data;

public Base64QRCodeRendererTests()
{
var gen = new QRCodeGenerator();
data = gen.CreateQrCode("This is a quick test! 123#?", QRCodeGenerator.ECCLevel.L);
}

[Fact]
[Category("QRRenderer/Base64QRCode")]
public void can_render_base64_qrcode_blackwhite()
{
var pngCodeGfx = new PngByteQRCode(data).GetGraphic(5);
var base64QRCode = new Base64QRCode(data).GetGraphic(5);
base64QRCode.ShouldBe(Convert.ToBase64String(pngCodeGfx));
}

[Fact]
[Category("QRRenderer/Base64QRCode")]
public void can_render_base64_qrcode_noquietzones()
{
var pngCodeGfx = new PngByteQRCode(data).GetGraphic(5, false);
var base64QRCode = new Base64QRCode(data).GetGraphic(5, Color.Black, Color.White, false);
base64QRCode.ShouldBe(Convert.ToBase64String(pngCodeGfx));
}

[Fact]
[Category("QRRenderer/Base64QRCode")]
public void can_render_base64_qrcode_color()
{
var pngCodeGfx = new PngByteQRCode(data).GetGraphic(5, new byte[] { 255, 0, 0 }, new byte[] { 0, 0, 255 });
var base64QRCode = new Base64QRCode(data).GetGraphic(5, Color.Red, Color.Blue);
base64QRCode.ShouldBe(Convert.ToBase64String(pngCodeGfx));
}

[Fact]
[Category("QRRenderer/Base64QRCode")]
public void can_render_base64_qrcode_transparent()
{
var pngCodeGfx = new PngByteQRCode(data).GetGraphic(5, new byte[] { 0, 255, 0, 255 }, new byte[] { 255, 255, 255, 0 });
var base64QRCode = new Base64QRCode(data).GetGraphic(5, Color.Lime, Color.Transparent);
base64QRCode.ShouldBe(Convert.ToBase64String(pngCodeGfx));
}

#if NETFRAMEWORK || NETCOREAPP2_0 || NET5_0 || NET6_0_WINDOWS
[Fact]
[Category("QRRenderer/Base64QRCode")]
public void can_render_base64_qrcode_jpeg()
{
var ms = new MemoryStream();
using (var bitmap = new QRCode(data).GetGraphic(5, Color.Black, Color.White, true))
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
}
ms.Position = 0;
var jpgString = Convert.ToBase64String(ms.ToArray());
var base64QRCode = new Base64QRCode(data).GetGraphic(5, Color.Black, Color.White, true, Base64QRCode.ImageType.Jpeg);
base64QRCode.ShouldBe(jpgString);
}
#endif
}
}

#endif
4 changes: 2 additions & 2 deletions QRCoderTests/Helpers/HelperFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#if !NETCOREAPP1_1
using System.Drawing;
#endif
#if NETFRAMEWORK || NET5_0_WINDOWS
#if NETFRAMEWORK || NET5_0_WINDOWS || NET6_0_WINDOWS
using SW = System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
Expand All @@ -17,7 +17,7 @@ namespace QRCoderTests.Helpers
public static class HelperFunctions
{

#if NETFRAMEWORK || NET5_0_WINDOWS
#if NETFRAMEWORK || NET5_0_WINDOWS || NET6_0_WINDOWS
public static BitmapSource ToBitmapSource(DrawingImage source)
{
DrawingVisual drawingVisual = new DrawingVisual();
Expand Down
1 change: 1 addition & 0 deletions QRCoderTests/QRCoderTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<UseWindowsForms Condition="'$(TargetFramework)' == 'net5.0-windows'">true</UseWindowsForms>
<UseWPF Condition="'$(TargetFramework)' == 'net5.0-windows'">true</UseWPF>
<DefineConstants Condition="'$(TargetFramework)' == 'net5.0-windows'">$(DefineConstants);NET5_0_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' == 'net6.0-windows'">$(DefineConstants);NET6_0_WINDOWS</DefineConstants>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
Expand Down
Loading