How to display a QR code in ASP.NET and WPF
I've half-jokingly said that there's never a good reason to use a QR Code. However, I'm working on an MVP (minimally viable product) for a small startup with Greg Shackles and we actually have a good reason to use one. We have a mobile device, a Web Site, and a Windows Application, and a QR Code is a pretty quick way to move data between the mobile device and the other applications without the mess of Bluetooth pairing.
As I mentioned, we display the QR code on an ASP.NET website, as well as within a Windows app that happens to be written in WPF. The iPhone app uses C# and Xamarin.
There's a great QR Code library called "ZXing" (Zebra Crossing) with ports in Java and also in C#. The C#/.NET one, ZXing.NET is a really fantastically well put together project with assemblies available for everything from .NET 2 to 4.5, Windows RT, Unity3D, Portable libraries and more. The site is filled with demo clients as well, although we didn't find one for ASP.NET or WPF. No matter, it's all just generating and showing PNGs.
I pulled in ZXing.NET from the NuGet package here, just install-package ZXing.Net.
How to display a QR code in ASP.NET
If you're generating a QR code with ASP.NET MVC, you'll have the page that the code lives on, but then you'll need to decide if you want to make an HTTP Handler that generates the graphic, like:
<img src="/path/to/httphandlerthatmakesQRcodepng">
or, you could take a different approach like we did, and embed the code in the HTML page itself.
Greg used an HTML Helper to output the entire image tag, including the inlined image, as in:
<img src="data:image/gif;base64,iVBORw0KG..." />
Images in HTML directly as Data URIs are super fun and I think, often forgotten. If you show one to the average web dev they'll say "oh, ya...I knew about those, but never really used it." In fact, Data URIs have been around for a LONG time. Learn more about them at DataUrl.net.
Here's generating a QR Code within ASP.NET MVC from an HTML Helper:
public static class HtmlHelperExtensions
{
public static IHtmlString GenerateRelayQrCode(this HtmlHelper html, string groupName, int height = 250, int width = 250, int margin = 0)
{
var qrValue = "whatever data you want to put in here";
var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = height,
Width = width,
Margin = margin
}
};
using (var bitmap = barcodeWriter.Write(qrValue))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Gif);
var img = new TagBuilder("img");
img.MergeAttribute("alt", "your alt tag");
img.Attributes.Add("src", String.Format("data:image/gif;base64,{0}",
Convert.ToBase64String(stream.ToArray())));
return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing));
}
}
}
Nice and simple. The BarcodeWriter class within ZXing.NET does the hard work. We don't need to save our QR Code to disk, and because we're doing it inline from our HTML page via this helper, there's no need for a separate call to get the image. Also, the caching policy that we decide to use for the page applies to the image within, simplifying things vs. two calls.
How to display a QR code in WPF
Note: This code here may be wrong. I'm happy to hear your suggestion, Dear Reader, because I'm either missing something completely or there is no clear and clean way to get from a System.Drawing.Bitmap to a System.Windows.Media.imaging.BitmapImage. The little dance here with the saving to a MemoryStream, then moving into a BitmapImage (with the unintuitive but totally required setting of CacheOption as well) just sets off my Spideysense. It can't be right, although it works.
I'll update the post when/if a cleaner way is found.
See below for update!
First, the exact same BarcodeWriter usage from the ZXing.NET library.
var qrcode = new QRCodeWriter();
var qrValue = "your magic here";
var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = 300,
Width = 300,
Margin = 1
}
};
using (var bitmap = barcodeWriter.Write(qrValue))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
stream.Seek(0, SeekOrigin.Begin);
bi.StreamSource = stream;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
QRCode.Source = bi; //A WPF Image control
}
Later, writing the Bitmap to a MemoryStream for manipulation, except in this case, we're putting the QR Code into the Source property of a WPF Image Control.
UPDATE: Thomas Levesque in the comments below suggests an extension within System.Windows.Interop (which explains me not finding it) called CreateBitmapSourceFromHBitmap. This still feels gross as it appears to requires a call to the native DeleteObject, but regardless, that's the price you pay I guess. It looks like this:
using (var bitmap = barcodeWriter.Write(qrValue))
{
var hbmp = bitmap.GetHbitmap();
try
{
var source = Imaging.CreateBitmapSourceFromHBitmap(hbmp, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
QRCode.Source = source;
}
finally
{
DeleteObject(hbmp);
}
}
It works well!
Sponsor: Big thanks to combit for sponsoring the blog feed this week! Enjoy feature-rich report designing: Discover the reporting tool of choice for thousands of developers. List & Label is an award-winning component with a royalty-free report designer. Free trial!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
I'll agree there are fewer reasons to use QR codes than actual uses.
My customer has one. They install industrial plant items that have dozens of settings. They need to produce a report for the commissioning engineers of what those settings are and why. Historically most of the settings got lost on scraps of paper in vans on the way back to the office.
Now they send the engineers out with a book of QRcode stickers. As they install equipment they slap a sticker on it. I built them a web site so that when they scan the sticker they get a web page to record the settings and why. Similarly when an engineer returns to it, they scan the code to find out who, what and why.
Eventually we'll dump the report and give the commissioning engineers logins to the site.
You are indeed missing something ;)
http://msdn.microsoft.com/en-us/library/system.windows.interop.imaging.createbitmapsourcefromhbitmap%28v=vs.110%29.aspx
(note that it returns a BitmapSource, not a BitmapImage, but it doesn't matter since the Image control accepts any ImageSource implementation)
http://chart.googleapis.com/chart?cht=qr&chs=300x300&chl=http://www.hanselman.com/blog/
Dynamically generated qr codes in asp.net
I know it is very crude and can be improved upon but works.
http://www.telerik.com/products/aspnet-ajax/barcode.aspx
However, I recently worked up a little application for a friend who teaches junior high: her school wanted to put QR codes on all the student's ID badges so the teachers could scan them when the student does something especially good. Then, the system keeps track of who has the most merit points and they give out prizes at the end of the month.
The cool thing is that the school's budget was zero, but I was still able to deliver what they wanted by using an open-source QR Code library and deploying to a free Windows Azure site.
I actually put the project up on GitHub in case anyone else would find such a thing useful.
For your information, some days ago I added a new download at codeplex for ZXing.Net which I called a "hotfix" ;). It contains a new zxing.presentation.dll which adds a BarcodeWriter class with an output of the type WriteableBitmap. That one integrates much better with WPF.
Next version of ZXing.Net will include that BarcodeWriter class.
trail marker
http://jeromeetienne.github.io/jquery-qrcode/
Eric W yes i am using windows phone ., the photo beamer is a cool app
Recently, writing a web app, which needed to have as much processing as possible on the client I came across this ...
http://d-project.googlecode.com/svn/trunk/misc/qrcode/index.html
With this nifty bit of js you can generate a gif on the client!
Everything that can be, will be :)
In the past you have frequently included code for WebPages....
Have you given up on us?
Comments are closed.