Skip to content

Commit

Permalink
Add ImageSharp renderers for .net 6.0, 5.0 and standart 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonKorn committed Jul 1, 2023
1 parent dd35a3b commit 70f644a
Show file tree
Hide file tree
Showing 10 changed files with 504 additions and 16 deletions.
92 changes: 92 additions & 0 deletions QRCoder.ImageSharp/ImageSharpBase64QRCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using SixLabors.ImageSharp.Formats;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace QRCoder.ImageSharp
{
public class ImageSharpBase64QRCode : AbstractQRCode, IDisposable
{
private ImageSharpQRCode qr;

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

public ImageSharpBase64QRCode(QRCodeData data)
: base(data)
{
qr = new ImageSharpQRCode(data);
}

public override void SetQRCodeData(QRCodeData data)
{
qr.SetQRCodeData(data);
}

public string GetGraphic(int pixelsPerModule)
{
return GetGraphic(pixelsPerModule, Color.Black, Color.White, true);
}

public string GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
return GetGraphic(pixelsPerModule, Color.Parse(darkColorHtmlHex), Color.Parse(lightColorHtmlHex), drawQuietZones, imgType);
}

public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
var base64 = string.Empty;
using (Image img = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones))
{
base64 = BitmapToBase64(img, imgType);
}

return base64;
}

public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Image icon, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
var base64 = string.Empty;
using (Image bmp = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, icon, iconSizePercent, iconBorderWidth, drawQuietZones))
{
base64 = BitmapToBase64(bmp, imgType);
}

return base64;
}

private string BitmapToBase64(Image img, ImageType imgType)
{
var base64 = string.Empty;
IImageEncoder iFormat;
switch (imgType)
{
default:
case ImageType.Png:
iFormat = new SixLabors.ImageSharp.Formats.Png.PngEncoder();
break;
case ImageType.Jpeg:
iFormat = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder();
break;
case ImageType.Gif:
iFormat = new SixLabors.ImageSharp.Formats.Gif.GifEncoder();
break;
}

using (var memoryStream = new MemoryStream())
{
img.Save(memoryStream, iFormat);
base64 = Convert.ToBase64String(memoryStream.ToArray(), Base64FormattingOptions.None);
}

return base64;
}
}
}
110 changes: 110 additions & 0 deletions QRCoder.ImageSharp/ImageSharpQRCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using static QRCoder.QRCodeGenerator;

namespace QRCoder.ImageSharp
{
public class ImageSharpQRCode : AbstractQRCode, IDisposable
{
/// <summary>
/// Constructor without params to be used in COM Objects connections
/// </summary>
public ImageSharpQRCode() { }

public ImageSharpQRCode(QRCodeData data)
: base(data) { }

public Image GetGraphic(int pixelsPerModule)
{
return GetGraphic(pixelsPerModule, Color.Black, Color.White, true);
}

public Image GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, bool drawQuietZones = true)
{
return GetGraphic(pixelsPerModule, Color.Parse(darkColorHtmlHex), Color.Parse(lightColorHtmlHex), drawQuietZones);
}

public Image GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true)
{
var moduleOffset = drawQuietZones ? 0 : 4;
var size = (QrCodeData.ModuleMatrix.Count - (moduleOffset * 2)) * pixelsPerModule;

var image = new Image<Rgba32>(size, size);
DrawQRCode(image, pixelsPerModule, moduleOffset, darkColor, lightColor);

return image;
}

public Image GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Image icon = null, int iconSizePercent = 15, int iconBorderWidth = 0, bool drawQuietZones = true, Color? iconBackgroundColor = null)
{
var img = GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones) as Image<Rgba32>;
if (icon != null && iconSizePercent > 0 && iconSizePercent <= 100)
{
var iconDestWidth = iconSizePercent * img.Width / 100f;
var iconDestHeight = iconDestWidth * icon.Height / icon.Width;
var iconX = (img.Width - iconDestWidth) / 2;
var iconY = (img.Height - iconDestHeight) / 2;
var centerDest = new RectangleF(iconX - iconBorderWidth, iconY - iconBorderWidth, iconDestWidth + (iconBorderWidth * 2), iconDestHeight + (iconBorderWidth * 2));
var iconDestRect = new RectangleF(iconX, iconY, iconDestWidth, iconDestHeight);

if (iconBorderWidth > 0)
{
if (!iconBackgroundColor.HasValue)
{
iconBackgroundColor = lightColor;
}

if (iconBackgroundColor != Color.Transparent)
{
img.ProcessPixelRows(accessor =>
{
for (var y = (int)centerDest.Top; y <= (int)centerDest.Bottom; y++)
{
var pixelRow = accessor.GetRowSpan(y);
for (var x = (int)centerDest.Left; x <= (int)centerDest.Right; x++)
{
pixelRow[x] = iconBackgroundColor ?? lightColor;
}
}
});
}
}

var sizedIcon = icon.Clone(x => x.Resize((int)iconDestWidth, (int)iconDestHeight));
img.Mutate(x => x.DrawImage(sizedIcon, new Point((int)iconDestRect.X, (int)iconDestRect.Y), 1));
}

return img;
}

private void DrawQRCode(Image<Rgba32> image, int pixelsPerModule, int moduleOffset, Color darkColor, Color lightColor)
{
var row = new Rgba32[image.Width];

image.ProcessPixelRows(accessor =>
{
for (var modY = moduleOffset; modY < QrCodeData.ModuleMatrix.Count - moduleOffset; modY++)
{
// Generate row for this y-Module
for (var modX = moduleOffset; modX < QrCodeData.ModuleMatrix.Count - moduleOffset; modX++)
{
for (var idx = 0; idx < pixelsPerModule; idx++)
{
row[((modX - moduleOffset) * pixelsPerModule) + idx] = this.QrCodeData.ModuleMatrix[modY][modX] ? darkColor : lightColor;
}
}
// Copy the prepared row to the image
for (var idx = 0; idx < pixelsPerModule; idx++)
{
var pixelRow = accessor.GetRowSpan(((modY - moduleOffset) * pixelsPerModule) + idx);
row.CopyTo(pixelRow);
}
}
});
}
}
}
8 changes: 0 additions & 8 deletions QRCoder/Base64QRCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using static QRCoder.Base64QRCode;
using static QRCoder.QRCodeGenerator;

namespace QRCoder
Expand Down Expand Up @@ -88,13 +87,6 @@ private string BitmapToBase64(Bitmap bmp, ImageType imgType)
return base64;
}

public enum ImageType
{
Gif,
Jpeg,
Png
}

}

#if NET6_0_WINDOWS
Expand Down
104 changes: 104 additions & 0 deletions QRCoder/ImageSharp/Base64QRCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System;
using System.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using static QRCoder.QRCodeGenerator;

namespace QRCoder.ImageSharp
{
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)
{
qr.SetQRCodeData(data);
}

public string GetGraphic(int pixelsPerModule)
{
return GetGraphic(pixelsPerModule, Color.Black, Color.White, true);
}

public string GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
return GetGraphic(pixelsPerModule, Color.Parse(darkColorHtmlHex), Color.Parse(lightColorHtmlHex), drawQuietZones, imgType);
}

public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
var base64 = string.Empty;
using (Image img = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, drawQuietZones))
{
base64 = BitmapToBase64(img, imgType);
}

return base64;
}

public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, Image icon, int iconSizePercent = 15, int iconBorderWidth = 6, bool drawQuietZones = true, ImageType imgType = ImageType.Png)
{
var base64 = string.Empty;
using (Image bmp = qr.GetGraphic(pixelsPerModule, darkColor, lightColor, icon, iconSizePercent, iconBorderWidth, drawQuietZones))
{
base64 = BitmapToBase64(bmp, imgType);
}

return base64;
}

private string BitmapToBase64(Image img, ImageType imgType)
{
var base64 = string.Empty;
IImageEncoder iFormat;
switch (imgType)
{
default:
case ImageType.Png:
iFormat = new SixLabors.ImageSharp.Formats.Png.PngEncoder();
break;
case ImageType.Jpeg:
iFormat = new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder();
break;
case ImageType.Gif:
iFormat = new SixLabors.ImageSharp.Formats.Gif.GifEncoder();
break;
}

using (var memoryStream = new MemoryStream())
{
img.Save(memoryStream, iFormat);
base64 = Convert.ToBase64String(memoryStream.ToArray(), Base64FormattingOptions.None);
}

return base64;
}
}

public static class ImageSharpBase64QRCodeHelper
{
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)
{
using (var qrGenerator = new QRCodeGenerator())
using (var qrCodeData = qrGenerator.CreateQrCode(plainText, eccLevel, forceUtf8, utf8BOM, eciMode, requestedVersion))
using (var qrCode = new Base64QRCode(qrCodeData))
{
return qrCode.GetGraphic(pixelsPerModule, darkColorHtmlHex, lightColorHtmlHex, drawQuietZones, imgType);
}
}
}
}

0 comments on commit 70f644a

Please sign in to comment.