Scott Hanselman

How to display a QR code in ASP.NET and WPF

January 19, '14 Comments [26] Posted in ASP.NET | NuGetPOW | WPF
Sponsored By

qrcode.19303638I'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. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Sunday, January 19, 2014 11:47:13 AM UTC
You could optimize the "dance" by serializing to BMP format. That's just a memcpy whereas a PNG is compressed.
tobi
Sunday, January 19, 2014 12:47:58 PM UTC
Hi Scott,

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.
Sunday, January 19, 2014 1:07:31 PM UTC
> 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.

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)
Sunday, January 19, 2014 1:31:58 PM UTC
You can also use Google to generate the qr image for you (forgive the recursion)

http://chart.googleapis.com/chart?cht=qr&chs=300x300&chl=http://www.hanselman.com/blog/
jim kennelly
Sunday, January 19, 2014 2:28:17 PM UTC
http://picturesofpeoplescanningqrcodes.tumblr.com

;)
Marcus Swope
Sunday, January 19, 2014 3:16:06 PM UTC
And this is how you can do it in Asp.net webforms with the same library:
Dynamically generated qr codes in asp.net

I know it is very crude and can be improved upon but works.
Sunday, January 19, 2014 4:11:07 PM UTC
Don't forget that control libraries from some of your favorite vendors have QRCode capabilities built in:

http://www.telerik.com/products/aspnet-ajax/barcode.aspx

Sunday, January 19, 2014 6:01:59 PM UTC
I've always been skeptical of QR codes, as they seem to mostly be used in advertisements for car dealerships on those ads they post above urinals in men's rooms.

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.
Sunday, January 19, 2014 7:37:25 PM UTC
You can use the Google Charts API to generate QR codes (known in the API as Infographics), however they have been deprecated by Google (April 2015? See https://developers.google.com/chart/infographics/). So you can't exactly plan your business on using that API for the long term.
Sunday, January 19, 2014 7:38:34 PM UTC
Thanks for using ZXing.Net and writing about it!
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.
Sunday, January 19, 2014 8:01:43 PM UTC
A surprisingly useful application for QR codes. On top of already informative trail markers (GPS, elevation, distance, etc.), a QR that links to more information for your position on the trail.
trail marker
Ethan
Monday, January 20, 2014 11:07:41 AM UTC
The open source project QRCodeNet has among others a WPF sample code and a ready to use WPF control to display QR codes.
Monday, January 20, 2014 12:49:13 PM UTC
Very useful :)
Monday, January 20, 2014 5:33:39 PM UTC
Great! I suddenly implemented this great library into my asp.net imagehandler (see http://bbimagehandler.codeplex.com)
Tuesday, January 21, 2014 1:22:52 AM UTC
In case you're interested, you can display a QR code in Xamarin.iOS using Core Image. Here's a gist: https://gist.github.com/mikebluestein/8532580
Tuesday, January 21, 2014 3:26:10 AM UTC
See also: http://www.nuget.org/packages?q=QRCode
Wednesday, January 22, 2014 2:53:44 AM UTC
Maybe this jQuery plugin would also help in ASP.NET pages. It can render QR code in two ways: table style and canvas style.

http://jeromeetienne.github.io/jquery-qrcode/
Wednesday, January 22, 2014 3:35:37 PM UTC
The coolest way I've seen QR codes is with the Nokia Windows Phones, they have an app called Photo Beamer where you visit the photobeamer website, scan a QR code with the app on the phone, and then you can "beam" pictures on the phone to display on the screen. Kind of a proof of concept of using QR codes for data transfer purposes (like what Scott mentioned).. but in this context, QR codes are pretty handy.
Saturday, February 15, 2014 12:07:40 PM UTC
nice job

Eric W yes i am using windows phone ., the photo beamer is a cool app
Sunday, February 23, 2014 10:36:17 AM UTC
I've used that chap in a previous project and it works well.

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 :)
Saturday, March 01, 2014 2:31:35 AM UTC
Scott,
In the past you have frequently included code for WebPages....

Have you given up on us?
wavemaster
Tuesday, March 04, 2014 2:47:44 AM UTC
wavemaster: No, what I showed works in WebPages also...what's the problem?
Monday, March 24, 2014 9:06:15 AM UTC
Terminate Protesting and complaining , Start Off your own special men Marketing plan As a substitute .
Monday, March 24, 2014 9:06:21 AM UTC
Consumers Used to Laugh at the japan - However Right Now I actually laugh at them
Monday, March 24, 2014 9:06:27 AM UTC
The very best technique for men you could discover right now.
Monday, March 24, 2014 9:06:33 AM UTC
The total technique for the men which you could learn straight away.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.