From 7e734e68a18e413239c986831308655d5cdf88bf Mon Sep 17 00:00:00 2001 From: Manuel Bl Date: Thu, 30 Dec 2021 11:13:16 +0100 Subject: [PATCH] QR code with image --- Demo-ImageSharp/Demo-ImageSharp.csproj | 10 +++++++ Demo-ImageSharp/Program.cs | 36 +++++++++++++++++++++++++ Demo-ImageSharp/README.md | 2 ++ Demo-ImageSharp/heart.png | Bin 0 -> 12497 bytes README.md | 2 +- 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 Demo-ImageSharp/heart.png diff --git a/Demo-ImageSharp/Demo-ImageSharp.csproj b/Demo-ImageSharp/Demo-ImageSharp.csproj index a3861b7..0170813 100644 --- a/Demo-ImageSharp/Demo-ImageSharp.csproj +++ b/Demo-ImageSharp/Demo-ImageSharp.csproj @@ -16,6 +16,16 @@ Codecrete + + + + + + + PreserveNewest + + + diff --git a/Demo-ImageSharp/Program.cs b/Demo-ImageSharp/Program.cs index 487d19e..1008be3 100644 --- a/Demo-ImageSharp/Program.cs +++ b/Demo-ImageSharp/Program.cs @@ -7,6 +7,8 @@ // https://opensource.org/licenses/MIT // +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Processing; using System; using System.IO; @@ -16,6 +18,13 @@ internal class Program { // Create a QR code and save it as a PNG. internal static void Main() + { + HelloWorld(); + QrCodeWithImage(); + } + + + internal static void HelloWorld() { var text = "Hello, world!"; var filename = "hello-world-QR.png"; @@ -25,5 +34,32 @@ internal static void Main() Console.WriteLine($"The QR code has been saved as {Path.GetFullPath(filename)}"); } + + internal static void QrCodeWithImage() + { + var text = "https://github.com/manuelbl/QrCodeGenerator"; + var filename = "qr-code-with-image.png"; + var logoFilename = "heart.png"; + const float logoWidth = 0.15f; // logo will have 15% the width of the QR code + + var qr = QrCode.EncodeText(text, QrCode.Ecc.Medium); + + using (var bitmap = qr.ToBitmap(scale: 10, border: 4)) + using (var logo = Image.Load(logoFilename)) + { + // resize logo + var w = (int)Math.Round(bitmap.Width * logoWidth); + logo.Mutate(logo => logo.Resize(w, 0)); + + // draw logo in center + var topLeft = new Point((bitmap.Width - logo.Width) / 2, (bitmap.Height - logo.Height) / 2); + bitmap.Mutate(img => img.DrawImage(logo, topLeft, 1)); + + // save as PNG + bitmap.SaveAsPng(filename); + } + + Console.WriteLine($"The QR code has been saved as {Path.GetFullPath(filename)}"); + } } } diff --git a/Demo-ImageSharp/README.md b/Demo-ImageSharp/README.md index adc440c..ad7cdc4 100644 --- a/Demo-ImageSharp/README.md +++ b/Demo-ImageSharp/README.md @@ -2,4 +2,6 @@ This example program shows how to create a QR code and save it as a PNG file using the [ImageSharp](https://github.com/SixLabors/ImageSharp) rasterization library. +Additionally, it demonstrates how to add an image in the center of the QR code. + The use of ImageSharp is recommended if the project already uses ImageSharp. diff --git a/Demo-ImageSharp/heart.png b/Demo-ImageSharp/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..622f3c05db1f3d5cb2bc6e08b70412dd5cd109ea GIT binary patch literal 12497 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