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. He is 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 SherWeb

Living a High-DPI desktop lifestyle can be painful

January 15, '14 Comments [108] Posted in Musings
Sponsored By

I've been using this Lenovo Yoga 2 Pro for the last few weeks, and lemme tell you, it's lovely. It's the perfect size, it weighs nothing, touch screen, fast SSD, it's thinner than the X1 Carbon Touch that is my primary machine, and it just feels right.

It also has about the nicest screen I've ever seen on a Windows Laptop.

Except. This thing runs at 3200x1800. That's FOUR of my 1600x900 ThinkPad X1 Carbon Touch screens.

Yes, 3200x1800

To be clear, full screen apps (Windows Store apps) almost universally look great. The text is clear, there's nary a pixel in sight. The whole full-screen Windows Store ecosystem seems to work nicely with high-DPI displays. And that makes sense, as it appears they've put a LOT of thought into high-dpi with Windows 8.1. I've changed a few settings on my 1080p Surface 2 in order to take better advantage of High-DPI and run a more apps simultaneously, in fact.

Also, note the checkbox that lets you set different scaling levels for different displays, so you can keep your laptop at high-res and an external monitor at another for example.

image

It's the Desktop where I get into trouble. First, let's look at the display at "small fonts."

NOTE: This is NOT the Default setting. The default is smart about the size of your screen and DPI and always tries to get the fonts looking the right size. I've changed the default to 100% to illustrate the massive number of pixels here.

3200x1800 is SO high res, that when you're running it at Small Fonts, well, a picture is worth a million pixels, right? Go ahead, click it, I'll wait. And you will also, it's 3 megs.

Holy Crap that's a lot of Pixels

Many, if not most apps work fine in the High-DPI desktop world. It's a little hard to get the point across in a blog post of screenshots because you, Dear Reader, are going to be reading this on a variety of displays. But I'll try.

Problems happen when applications either totally don't think about High-DPI displays, or more commonly, they kind of think about them.

You can say all this talk of High-DPI is a problem with Windows, but I think it's a problem with the app developers. The documentation is clear on High-DPI and developers need to test, include appropriate resources or don't claim to support high-dpi. I have a number of older Windows apps that look great on this display. They are simply scaled at 2x. Sure, they may be a little blurry (they have been scaled 2x) but they are all 100% useable.

NOTE: There's a very technical session on getting high-dpi to look good in Windows Desktop apps at BUILD. The Video is here.

Here's a few examples that have caused me pain in just the last week, as well as some Good Citizen apps that look great at High-DPI.

Examples of Poor High-DPI behavior

Let's start with Windows Live Writer, one of my favorite apps and the app I'm using to write this post. It almost looks great, presumably because it's a WPF application and WPF is pretty good about DPI things. However, note the pictures. They are exactly half the size of reality. Well, let me be more clear. They are exactly pixel-sized. They are the size they are, rather than scaled to 200%. This has caused me to upload either giant pics or too-small pics because WLW scales text at one size and images at another, within the same document!

image

Adobe everything. I am shocked at how bad Adobe stuff looks on a high-dpi display. Just flip a coin, chances are it's gonna be a mix of small and large. Here's Adobe Reader.

image

Here's the Flash installer.

Screenshot (16)

Here's a great example - Dropbox.

image

Dropbox gets worse the deeper you get into the menus.

image

SQL Server Management Studio is a bad example.

OYhVDR8

Here's an easy fix, just add high-res arrow resources, or draw them with a vector.

BG9hS2W

Examples of Good High-DPI behavior

Visual Studio 2013 looks great. Fonts are well-sized, and while the icons aren't high-res (retina) they still look ok. All the Dialog boxes and menus work as they should.

image

Word 2013 and all of Office look great at High-DPI. They've got great icons, great fonts and generally are awesome.

image

Paint.NET 4.0 Alpha also looks great. There's some scaled icons, but the app is smart and there's pixel perfect editing.

image

GitHub for Windows looks awesome at High-DPI.

image

Do you have any examples of high-DPI frustration on the Desktop? Upload them to ImgUr.com and link to them in the comments!

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.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Finding a low-memory browser

January 8, '14 Comments [64] Posted in Musings
Sponsored By
Three Browsers and their memory usage

I'm testing a 4GB Lenovo Yoga Pro 2 this week and I'm finding I'm running right up against the 4 gigs of RAM in my daily work. I usually have Visual Studio open, a browser, and a few other apps. I have IE, Chrome, and Firefox pinned in my Taskbar and usually work in Chrome. I (this just happened to be) had these tabs open:

  • Outlook.com (work email), Gmail (home email), Twitter.com, TroyHunt.com, StackOverflow.com, ArsTechnica.com, Amazon.com

Here's my task manager showing the Chrome "Canary" processes:

image

And here's the internal Chrome task manager (which is great!) showing what's really happening:

image

Certainly the memory used by my growing collection of Chrome extensions adds up. Some tabs that are "apps" like Gmail and Outlook use a 100megs or more. Regular "pages" (things that aren't heavy JS users) like Troy's blog or ArsTechnical use maybe 10megs.

If I run a small PowerShell script to collect the chrome.exe's and sum their physical memory use:

$m = ps chrome  | measure PM -Sum ; ("Chrome  {0:N2}MB " -f ($m.sum / 1mb))

I get about 1.6 gigs! On a 4 gig machine. Ouch.

C:\> .\memory.ps1
Chrome 1,623.08MB

Virtual Memory is even worse, at 6.3gigs! I start to trim the extension-fat by going to Tools | Extensions and disabling extensions I don't need now. If I'm debugging JSON, for example, I'll turn JSONView back on as needed.

Modifying my script to measure both Virtual and Physical Memory and running again with ALL non-essential plugins turned off.

C:\> .\memory.ps1
Chrome PM 1,151.72MB
Chrome VM 4,056.56MB

Big changes. Clearly the plugin thing can get out of hand quickly and running too many on a low-memory machine is a killer. I got a half-gig of memory back disabling my extraneous extensions.

Let me try the same seven sites in IE11 with no add-ons (extensions) enabled either:

IE      PM 604.11MB
IE VM 1,801.23MB

Nice improvement, less than half the VM and just over 600 megs PM. Now I'll try Firefox "Aurora." Again, same sites, logged in and running in the same state:

Firefox PM 426.58MB
Firefox VM 824.02MB

Nice. Some excellent memory optimization work happening at Mozilla it seems.

Of course, this is just 7 random sites that I happened to be visiting. Here's my poorly written PowerShell script memory.ps1

$m = ps chrome  | measure PM -Sum ; ("Chrome PM {0:N2}MB " -f ($m.sum / 1mb))
$m = ps chrome | measure VM -Sum ; ("Chrome VM {0:N2}MB " -f ($m.sum / 1mb))

$m = ps firefox | measure PM -Sum ; ("Firefox PM {0:N2}MB " -f ($m.sum / 1mb))
$m = ps firefox | measure VM -Sum ; ("Firefox VM {0:N2}MB " -f ($m.sum / 1mb))

$m = ps iexplore| measure PM -Sum ; ("IE PM {0:N2}MB " -f ($m.sum / 1mb))
$m = ps iexplore| measure VM -Sum ; ("IE VM {0:N2}MB " -f ($m.sum / 1mb))

It may be that these browser builds aren't all optimize for memory usage. I don't know. They were/are the ones I have on my machine and the ones I use. Your system, your sites, your browser builds, and your video card will change these results. Measure for yourself.

For me, I need more RAM. 4gigs just isn't reasonable no matter what browser you're running.

UPDATE: A commenter below says my results are flawed as I'm not taking into consideration how shared memory works. I am not sure (yet) I agree. Here is Chrome's about:memory feature. Who can offer thoughts?

image

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.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Switch easily between VirtualBox and Hyper-V with a BCDEdit boot Entry in Windows 8.1

January 8, '14 Comments [19] Posted in Tools
Sponsored By

I've been using GenyMotion for a FAST Android Emulator when developing with Visual Studio and Xamarin. However, I also use Hyper-V when developing for Windows Phone. GenyMotion use VirtualBox, which has it's own Hypervisor and you can't have two.

Some sites say to use Add/Remove Features to turn the Hyper-V support off, but that seems like a big deal to do what should be a small thing.

Instead, from an administrative command prompt I made a copy of my boot menu with a "No Hyper-V" entry:

Note the first command gives you a GUID and you then copy it and use it with the second command.

C:\>bcdedit /copy {current} /d "No Hyper-V" 
The entry was successfully copied to {ff-23-113-824e-5c5144ea}.

C:\>bcdedit /set {ff-23-113-824e-5c5144ea} hypervisorlaunchtype off
The operation completed successfully.

Now, this is important. In Windows 8.x, Windows is optimized to startup FAST. And it does. On my Lenovo it starts in about 3 seconds, faster than I can press any buttons to interrupt it. But when I want to dual boot, I need it to really shut down and give me an option to chose this new boot menu.

In order to access the new boot menu, I select Settings (Windows Key + C) then Power, and Restart but hold down shift on the keyboard while clicking Restart with the mouse.

HOLD SHIFT while pressing Restart

You will get this scary looking Blue Screen. Select "Other Operating Systems" and your "No Hyper-V" option is in there.

Windows 8.1 Boot Menu

Selecting No Hyper-V

Now, you can run Virtual Box nicely but still choose Hyper-V when you want. You can confirm VirtualBox works by noting that the Acceleration tab will not be grayed out under System Settings for your VMs. Reboot normally and Hyper-V will be back and ready to go. Here's Android running in VirtualBox via GenyMotion.

Android in an x86 VM in GenyMotion under Virtual Box - Used for Xamarin and Visual Studio Android Development in C#

There's touch support too! If you're not doing Android development like this with Visual Studio and Xamarin, frankly, you're missing out.

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.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The new Information Worker Resume or CV Template

January 7, '14 Comments [18] Posted in Musings
Sponsored By

Scott Hanselman, Information Worker

Objective

To find a position with a dynamic and progressive technology company that utilizes my leadership abilities and skills deleting email.

Experience

Line Engineer - Gmail - Google

  • Designed and implemented a system wherein two gmail accounts with autoresponders replied to each other in a loop until one achieved sentience.
  • {I have|I've} been {reading|skimming|pretending to read} e-mails {5 years|10 years|decades|please make it stop}, and yours is definitely one of the {best|most interesting|most thoughtfully written}. {It's|It is} brightened my day and compelled me to {schedule a follow-up meeting|create a recurring meeting|create a high priority rule just for you}. {By all means|Please|I humbly beg you}, don't hesitate to e-mail me again, perhaps expanding your to a wider list?

Product Manager - Microsoft Outlook - Microsoft

  • Formulated models to determine team synergies and core competencies based entirely on depth of e-mail threads. This information fed directly into stack ranking calculations at a large unnamed software corporation in the Pacific Northwest
  • Investigated "Predictive Email Deletion" in which a sender's e-mail would be remotely deleted before it was sent.

Junior Project Manager - Yahoo! Mail - Yahoo

  • Worked on the team that pioneered the technique of sending another email after an unsubscribe request.
  • Spearheaded a study group to determine if remote workers could be contacted via e-mail. Was eventually fired as the last remote worker.

Education

Masters Degree in Computer Science

Thesis work on "The Anatomy of a Large-Scale Email Deletion Engine." I set out to prove that one could dramatically increase throughput and productivity through the use of Ctrl-A and Delete in large scale information systems. I successfully proved that information worker productivity scales linearly with e-mail deletion, and as such those with the most email should be in charge.

Bachelors of Science in Software Engineering and Product Management

Explored the psychological efforts on team dynamics of having a project manager with "1000+" in every folder in Microsoft Outlook. Teams of up to 20 people experienced disintegration of cultural barriers and constructive synergies once the first direct manager lost control of their inbox. Cannibalism quickly followed.

Volunteerism

  • Quora For Kids - Board member of non-profit dedicated to teaching kids how to unsubscribe from Quora emails.
  • Community Committee for Email Compliance - Outreach 501c3 with the mission to increase visibility of the laws around having an email signature longer than the email itself.
    • Privileged/Confidential information may be contained in this resume and may be subject to legal privilege. Access to this resume by anyone other than the intended is unauthorized. If you are not the intended recipient (or responsible for delivery of the message to such person), you may not use, copy, distribute or deliver to anyone this resume (or any part of its contents ) or take any action in reliance on it. In such case, you should destroy this message, and notify us immediately. If you have received this resume in error, please notify us immediately by postcard, fax, telegram, courier, or telephone and delete the resume from any computer. If you or your employer does not consent to resumes of this kind, please notify us immediately. All reasonable precautions have been taken to ensure no viruses are present in this resume. As our company cannot accept responsibility for any loss or damage arising from the use of this resume or attachments we recommend that you subject these to your virus checking procedures prior to use. The views, opinions, conclusions and other information expressed in this CV are not given or endorsed by the company unless otherwise indicated by an authorized representative independent of this message.

References

Please send email for references.


Going to SXSW? Come see me at 5pm on March 10th talk about email, productivity, and how to truly stay sane.

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.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

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