Skip to content

Commit 1f30305

Browse files
committed
ASP.NET Core demo
1 parent 7e734e6 commit 1f30305

14 files changed

+504
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
<RootNamespace>Net.Codecrete.QrCodeGenerator.Demo</RootNamespace>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Net.Codecrete.QrCodeGenerator" Version="2.0.0" />
10+
<PackageReference Include="SkiaSharp" Version="2.80.3" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31919.166
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo-ASP.NET-Core", "Demo-ASP.NET-Core.csproj", "{8EA82CD7-A88E-4A93-94B0-FA0C7DD1C7F1}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{8EA82CD7-A88E-4A93-94B0-FA0C7DD1C7F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{8EA82CD7-A88E-4A93-94B0-FA0C7DD1C7F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{8EA82CD7-A88E-4A93-94B0-FA0C7DD1C7F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{8EA82CD7-A88E-4A93-94B0-FA0C7DD1C7F1}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {2902DABB-C256-46C5-AF46-35600F5F7A0E}
24+
EndGlobalSection
25+
EndGlobal

Demo-ASP.NET-Core/Program.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// QR code generator library (.NET)
3+
// https://github.com/manuelbl/QrCodeGenerator
4+
//
5+
// Copyright (c) 2021 Manuel Bleichenbacher
6+
// Licensed under MIT License
7+
// https://opensource.org/licenses/MIT
8+
//
9+
10+
using Microsoft.AspNetCore.Hosting;
11+
using Microsoft.Extensions.Hosting;
12+
13+
namespace Net.Codecrete.QrCodeGenerator.Demo
14+
{
15+
public class Program
16+
{
17+
public static void Main(string[] args)
18+
{
19+
CreateHostBuilder(args).Build().Run();
20+
}
21+
22+
public static IHostBuilder CreateHostBuilder(string[] args) =>
23+
Host.CreateDefaultBuilder(args)
24+
.ConfigureWebHostDefaults(webBuilder =>
25+
{
26+
webBuilder.UseStartup<Startup>();
27+
});
28+
}
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:25726",
7+
"sslPort": 44337
8+
}
9+
},
10+
"profiles": {
11+
"IIS Express": {
12+
"commandName": "IISExpress",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNETCORE_ENVIRONMENT": "Development"
16+
}
17+
},
18+
"Demo_ASP.NET_Core": {
19+
"commandName": "Project",
20+
"dotnetRunMessages": "true",
21+
"launchBrowser": true,
22+
"applicationUrl": "https://localhost:5001;http://localhost:5000",
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
}
26+
}
27+
}
28+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
//
2+
// QR code generator library (.NET)
3+
// https://github.com/manuelbl/QrCodeGenerator
4+
//
5+
// Copyright (c) 2021 Manuel Bleichenbacher
6+
// Licensed under MIT License
7+
// https://opensource.org/licenses/MIT
8+
//
9+
10+
using SkiaSharp;
11+
using System;
12+
using System.IO;
13+
14+
namespace Net.Codecrete.QrCodeGenerator
15+
{
16+
public static class QrCodeBitmapExtensions
17+
{
18+
/// <inheritdoc cref="ToBitmap(QrCode, int, int)"/>
19+
/// <param name="background">The background color.</param>
20+
/// <param name="foreground">The foreground color.</param>
21+
public static SKBitmap ToBitmap(this QrCode qrCode, int scale, int border, SKColor foreground, SKColor background)
22+
{
23+
// check arguments
24+
if (scale <= 0)
25+
{
26+
throw new ArgumentOutOfRangeException(nameof(scale), "Value out of range");
27+
}
28+
if (border < 0)
29+
{
30+
throw new ArgumentOutOfRangeException(nameof(border), "Value out of range");
31+
}
32+
33+
int size = qrCode.Size;
34+
int dim = (size + border * 2) * scale;
35+
36+
if (dim > short.MaxValue)
37+
{
38+
throw new ArgumentOutOfRangeException(nameof(scale), "Scale or border too large");
39+
}
40+
41+
// create bitmap
42+
SKBitmap bitmap = new SKBitmap(dim, dim, SKColorType.Rgb888x, SKAlphaType.Opaque);
43+
44+
using (SKCanvas canvas = new SKCanvas(bitmap))
45+
{
46+
// draw background
47+
using (SKPaint paint = new SKPaint { Color = background })
48+
{
49+
canvas.DrawRect(0, 0, dim, dim, paint);
50+
}
51+
52+
// draw modules
53+
using (SKPaint paint = new SKPaint { Color = foreground })
54+
{
55+
for (int y = 0; y < size; y++)
56+
{
57+
for (int x = 0; x < size; x++)
58+
{
59+
if (qrCode.GetModule(x, y))
60+
{
61+
canvas.DrawRect((x + border) * scale, (y + border) * scale, scale, scale, paint);
62+
}
63+
}
64+
}
65+
}
66+
}
67+
68+
return bitmap;
69+
}
70+
71+
/// <summary>
72+
/// Creates a bitmap (raster image) of this QR code.
73+
/// <para>
74+
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
75+
/// equivalent to the width and height of each QR code module. Additionally, the number
76+
/// of modules to add as a border to all four sides can be specified.
77+
/// </para>
78+
/// <para>
79+
/// For example, <c>ToBitmap(scale: 10, border: 4)</c> means to pad the QR code with 4 white
80+
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
81+
/// </para>
82+
/// <para>
83+
/// The resulting bitmap uses the pixel format <see cref="PixelFormat.Format24bppRgb"/>.
84+
/// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
85+
/// </para>
86+
/// </summary>
87+
/// <param name="scale">The width and height, in pixels, of each module.</param>
88+
/// <param name="border">The number of border modules to add to each of the four sides.</param>
89+
/// <returns>The created bitmap representing this QR code.</returns>
90+
/// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
91+
/// or the resulting image is wider than 32,768 pixels.</exception>
92+
public static SKBitmap ToBitmap(this QrCode qrCode, int scale, int border)
93+
{
94+
return qrCode.ToBitmap(scale, border, SKColors.Black, SKColors.White);
95+
}
96+
97+
/// <inheritdoc cref="ToPng(QrCode, int, int)"/>
98+
/// <param name="background">The background color.</param>
99+
/// <param name="foreground">The foreground color.</param>
100+
public static byte[] ToPng(this QrCode qrCode, int scale, int border, SKColor foreground, SKColor background)
101+
{
102+
using SKBitmap bitmap = qrCode.ToBitmap(scale, border, foreground, background);
103+
using SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 90);
104+
return data.ToArray();
105+
}
106+
107+
/// <summary>
108+
/// Creates a PNG image of this QR code and returns it as a byte array.
109+
/// <para>
110+
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
111+
/// equivalent to the width and height of each QR code module. Additionally, the number
112+
/// of modules to add as a border to all four sides can be specified.
113+
/// </para>
114+
/// <para>
115+
/// For example, <c>ToPng(scale: 10, border: 4)</c> means to pad the QR code with 4 white
116+
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
117+
/// </para>
118+
/// <para>
119+
/// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
120+
/// </para>
121+
/// </summary>
122+
/// <param name="scale">The width and height, in pixels, of each module.</param>
123+
/// <param name="border">The number of border modules to add to each of the four sides.</param>
124+
/// <returns>The created bitmap representing this QR code.</returns>
125+
/// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
126+
/// or the resulting image is wider than 32,768 pixels.</exception>
127+
public static byte[] ToPng(this QrCode qrCode, int scale, int border)
128+
{
129+
return qrCode.ToPng(scale, border, SKColors.Black, SKColors.White);
130+
}
131+
132+
/// <inheritdoc cref="SaveAsPng(QrCode, string, int, int)"/>
133+
/// <param name="background">The background color.</param>
134+
/// <param name="foreground">The foreground color.</param>
135+
public static void SaveAsPng(this QrCode qrCode, string filename, int scale, int border, SKColor foreground, SKColor background)
136+
{
137+
using SKBitmap bitmap = qrCode.ToBitmap(scale, border, foreground, background);
138+
using SKData data = bitmap.Encode(SKEncodedImageFormat.Png, 90);
139+
using FileStream stream = File.OpenWrite(filename);
140+
data.SaveTo(stream);
141+
}
142+
143+
/// <summary>
144+
/// Saves this QR code as a PNG file.
145+
/// <para>
146+
/// The <paramref name="scale"/> parameter specifies the scale of the image, which is
147+
/// equivalent to the width and height of each QR code module. Additionally, the number
148+
/// of modules to add as a border to all four sides can be specified.
149+
/// </para>
150+
/// <para>
151+
/// For example, <c>SaveAsPng("qrcode.png", scale: 10, border: 4)</c> means to pad the QR code with 4 white
152+
/// border modules on all four sides, and use 10&#xD7;10 pixels to represent each module.
153+
/// </para>
154+
/// <para>
155+
/// If not specified, the foreground color is black (0x000000) und the background color always white (0xFFFFFF).
156+
/// </para>
157+
/// </summary>
158+
/// <param name="scale">The width and height, in pixels, of each module.</param>
159+
/// <param name="border">The number of border modules to add to each of the four sides.</param>
160+
/// <exception cref="ArgumentOutOfRangeException"><paramref name="scale"/> is 0 or negative, <paramref name="border"/> is negative
161+
/// or the resulting image is wider than 32,768 pixels.</exception>
162+
public static void SaveAsPng(this QrCode qrCode, string filename, int scale, int border)
163+
{
164+
qrCode.SaveAsPng(filename, scale, border, SKColors.Black, SKColors.White);
165+
}
166+
}
167+
}

Demo-ASP.NET-Core/QrCodeController.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// QR code generator library (.NET)
3+
// https://github.com/manuelbl/QrCodeGenerator
4+
//
5+
// Copyright (c) 2021 Manuel Bleichenbacher
6+
// Licensed under MIT License
7+
// https://opensource.org/licenses/MIT
8+
//
9+
10+
using Microsoft.AspNetCore.Mvc;
11+
using System;
12+
using System.Text;
13+
14+
namespace Net.Codecrete.QrCodeGenerator.Demo
15+
{
16+
/// <summary>
17+
/// Controller for generating QR code as PNG or SVG images
18+
/// </summary>
19+
[ApiController]
20+
public class QrCodeController : ControllerBase
21+
{
22+
private static readonly QrCode.Ecc[] errorCorrectionLevels = { QrCode.Ecc.Low, QrCode.Ecc.Medium, QrCode.Ecc.Quartile, QrCode.Ecc.High };
23+
24+
/// <summary>
25+
/// Generates QR code as PNG image
26+
/// </summary>
27+
/// <param name="text">Text to encode in QR code</param>
28+
/// <param name="ecc">Error correction level (0: low ... 3: high)</param>
29+
/// <param name="borderWidth">Border width in multiples of a module (QR code pixel)</param>
30+
/// <returns>PNG image</returns>
31+
[HttpGet("qrcode/png")]
32+
[ResponseCache(Duration = 2592000)]
33+
public ActionResult<byte[]> GeneratePng([FromQuery(Name = "text")] string text,
34+
[FromQuery(Name = "ecc")] int? ecc, [FromQuery(Name = "border")] int? borderWidth)
35+
{
36+
ecc = Math.Clamp(ecc ?? 1, 0, 3);
37+
borderWidth = Math.Clamp(borderWidth ?? 3, 0, 999999);
38+
39+
var qrCode = QrCode.EncodeText(text, errorCorrectionLevels[(int)ecc]);
40+
byte[] png = qrCode.ToPng(20, (int)borderWidth);
41+
return new FileContentResult(png, "image/png");
42+
}
43+
44+
/// <summary>
45+
/// Generates QR code as SVG image
46+
/// </summary>
47+
/// <param name="text">Text to encode in QR code</param>
48+
/// <param name="ecc">Error correction level (0: low ... 3: high)</param>
49+
/// <param name="borderWidth">Border width in multiples of a module (QR code pixel)</param>
50+
/// <returns>SVG image</returns>
51+
[HttpGet("qrcode/svg")]
52+
[ResponseCache(Duration = 2592000)]
53+
public ActionResult<byte[]> GenerateSvg([FromQuery(Name = "text")] string text,
54+
[FromQuery(Name = "ecc")] int? ecc, [FromQuery(Name = "border")] int? borderWidth)
55+
{
56+
ecc = Math.Clamp(ecc ?? 1, 0, 3);
57+
borderWidth = Math.Clamp(borderWidth ?? 3, 0, 999999);
58+
59+
var qrCode = QrCode.EncodeText(text, errorCorrectionLevels[(int)ecc]);
60+
byte[] svg = Encoding.UTF8.GetBytes(qrCode.ToSvgString((int)borderWidth));
61+
return new FileContentResult(svg, "image/svg+xml; charset=utf-8");
62+
}
63+
}
64+
}

Demo-ASP.NET-Core/README..md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Sample code for ASP.NET Core
2+
3+
This example program shows how to create a QR codes in an ASP.NET core application.
4+
5+
The [`QrCodeController`](QrCodeController.cs) class receives the QR code text, border width and error correction level as query parameters and generates the QR code, either as an SVG or PNG.
6+
7+
For PNG generation, the [SkiaSharp](https://github.com/mono/SkiaSharp) rasterization library is used.

Demo-ASP.NET-Core/Startup.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// QR code generator library (.NET)
3+
// https://github.com/manuelbl/QrCodeGenerator
4+
//
5+
// Copyright (c) 2021 Manuel Bleichenbacher
6+
// Licensed under MIT License
7+
// https://opensource.org/licenses/MIT
8+
//
9+
10+
using Microsoft.AspNetCore.Builder;
11+
using Microsoft.AspNetCore.Hosting;
12+
using Microsoft.AspNetCore.Rewrite;
13+
using Microsoft.Extensions.DependencyInjection;
14+
using Microsoft.Extensions.Hosting;
15+
16+
namespace Net.Codecrete.QrCodeGenerator.Demo
17+
{
18+
public class Startup
19+
{
20+
// This method gets called by the runtime. Use this method to add services to the container.
21+
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
22+
public void ConfigureServices(IServiceCollection services)
23+
{
24+
services.AddControllers();
25+
}
26+
27+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
28+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
29+
{
30+
if (env.IsDevelopment())
31+
{
32+
app.UseDeveloperExceptionPage();
33+
}
34+
35+
var rewriter = new RewriteOptions();
36+
rewriter.AddRewrite("^$", "home.html", skipRemainingRules: false);
37+
app.UseRewriter(rewriter);
38+
39+
app.UseStaticFiles();
40+
41+
app.UseRouting();
42+
43+
app.UseEndpoints(endpoints =>
44+
{
45+
endpoints.MapControllers();
46+
});
47+
}
48+
}
49+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)