Skip to content

Commit

Permalink
Add Magick.NET demo
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelbl committed Jul 26, 2022
1 parent 9f064a0 commit 907e7a9
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Demo-ImageMagick/Demo-ImageMagick.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Net.Codecrete.QrCodeGenerator.Demo</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="11.3.0" />
<PackageReference Include="Net.Codecrete.QrCodeGenerator" Version="2.0.3" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions Demo-ImageMagick/Demo-ImageMagick.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32630.192
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo-ImageMagick", "Demo-ImageMagick.csproj", "{E4F86D1E-F08C-4BFE-BC37-9BED8A411E88}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E4F86D1E-F08C-4BFE-BC37-9BED8A411E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E4F86D1E-F08C-4BFE-BC37-9BED8A411E88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4F86D1E-F08C-4BFE-BC37-9BED8A411E88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4F86D1E-F08C-4BFE-BC37-9BED8A411E88}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BC2EF2FB-30F7-431B-B92C-05E9C7B7B07B}
EndGlobalSection
EndGlobal
18 changes: 18 additions & 0 deletions Demo-ImageMagick/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// QR code generator library (.NET)
// https://github.com/manuelbl/QrCodeGenerator
//
// Copyright (c) 2022 suxiaobu9, Manuel Bleichenbacher
// Licensed under MIT License
// https://opensource.org/licenses/MIT
//

using ImageMagick;
using Net.Codecrete.QrCodeGenerator;

string text = "Hello, world!",
fileName = "hello-world-QR.png";

var qr = QrCode.EncodeText(text, QrCode.Ecc.Medium);

qr.SaveAsPng(fileName, 10, 4, MagickColors.Black, MagickColors.White);
123 changes: 123 additions & 0 deletions Demo-ImageMagick/QrCodeImageExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//
// QR code generator library (.NET)
// https://github.com/manuelbl/QrCodeGenerator
//
// Copyright (c) 2022 suxiaobu9, Manuel Bleichenbacher
// Licensed under MIT License
// https://opensource.org/licenses/MIT
//

using ImageMagick;

namespace Net.Codecrete.QrCodeGenerator;

public static class QrCodeImageExtensions
{
/// <summary>
/// Creates a image of this QR code.
/// <para>
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
/// equivalent to the width and height of each QR code module. Additionally, the number
/// of modules to add as a border to all four sides can be specified.
/// </para>
/// <para>
/// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR code with 4 white
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
/// </para>
/// </summary>
/// <param name="scale">The width and height, in pixels, of each module.</param>
/// <param name="border">The number of border modules to add to each of the four sides.</param>
/// <param name="background">The background color.</param>
/// <param name="foreground">The foreground color.</param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static MagickImage ToImage(this QrCode qrCode, int scale, int border, MagickColor foreground, MagickColor background)
{
if (scale <= 0)
{
throw new ArgumentOutOfRangeException(nameof(scale), " Value out of range");
}

if (border < 0)
{
throw new ArgumentOutOfRangeException(nameof(border), " Value out of range");
}

var size = qrCode.Size;
var dim = (size + border * 2) * scale;

if (dim > short.MaxValue)
{
throw new ArgumentOutOfRangeException(nameof(scale), " Scale or border too large");
}

var image = new MagickImage(background, dim, dim)
{
Format = MagickFormat.Png,
};

var drawables = new Drawables();
drawables.FillColor(foreground);

for (var x = 0; x < size; x++)
{
var pointerX = (x + border) * scale;

for (var y = 0; y < size; y++)
{
if (qrCode.GetModule(x, y))
{
var pointerY = (y + border) * scale;
drawables.Rectangle(pointerX, pointerY, pointerX + scale - 1, pointerY + scale - 1);
}
}
}
drawables.Draw(image);
return image;
}

/// <summary>
/// Creates a PNG image of this QR code and returns it as a byte array.
/// <para>
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
/// equivalent to the width and height of each QR code module. Additionally, the number
/// of modules to add as a border to all four sides can be specified.
/// </para>
/// <para>
/// For example, <c>ToPng(scale: 10, border: 4)</c> means to pad the QR code with 4 white
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
/// </para>
/// </summary>
/// <param name="scale">The width and height, in pixels, of each module.</param>
/// <param name="border">The number of border modules to add to each of the four sides.</param>
/// <param name="foreground">The foreground color.</param>
/// <param name="background">The background color.</param>
/// <returns></returns>
public static byte[] ToPng(this QrCode qrCode, int scale, int border, MagickColor foreground, MagickColor background)
{
using var image = qrCode.ToImage(scale, border, foreground, background);
return image.ToByteArray();
}

/// <summary>
/// Saves this QR code as a PNG file.
/// <para>
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
/// equivalent to the width and height of each QR code module. Additionally, the number
/// of modules to add as a border to all four sides can be specified.
/// </para>
/// <para>
/// For example, <c>SaveAsPng("qrcode.png", scale: 10, border: 4)</c> means to pad the QR code with 4 white
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
/// </para>
/// </summary>
/// <param name="scale">The width and height, in pixels, of each module.</param>
/// <param name="border">The number of border modules to add to each of the four sides.</param>
/// <param name="foreground">The foreground color.</param>
/// <param name="background">The background color.</param>
public static void SaveAsPng(this QrCode qrCode, string fileName, int scale, int border, MagickColor foreground, MagickColor background)
{
using var image = qrCode.ToImage(scale, border, foreground, background);
image.Write(fileName);
}
}
3 changes: 3 additions & 0 deletions Demo-ImageMagick/README.me
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Saving as PNG using Magick.NET

This example program shows how to create a QR code and save it as a PNG file using the [Magick.NET](https://github.com/dlemstra/Magick.NET) image manipulation library (based on ImageMagick).
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,5 @@ Several example projects are provided:
- [Demo-SkiaSharp](Demo-SkiaSharp): Demonstrates how a QR code can be saved a PNG file, using the SkiaSharp multi-platform raster image library.

- [Demo-ImageSharp](Demo-ImageSharp): Demonstrates how a QR code can be saved a PNG file, using the ImageSharp raster image library. Additionally, a QR code with an image in the center is created.

- [Demo-SkiaSharp](Demo-ImageMagick): Demonstrates how a QR code can be saved a PNG file, using the Magick.NET image manipulation library (based on ImageMagick).

0 comments on commit 907e7a9

Please sign in to comment.