It’s been a long time since my last post about C# but I’m still using it, mainly for a personal project: UrzaGatherer 3.0.
Version 2.0 was done using WinJS and JavaScript but because I love discovering new things I decided that version 3.0 will be developed using C# and XAML for Windows 10.
One of the feature I’m working on is a blurred lockscreen background. Basically, the idea is to pick a card and use the picture as lockscreen background.
The main problem that I was facing is that the cards scans are in a too low resolution. So to get rid of the inevitable aliasing produced by scaling my pictures up, I decided to add some Gaussian blur.
The first version of my blurred lockscreen background used a kind of brute force approach: Going through all the pixels and applying my filter. On my desktop PC: no problem. But on my phone (Remember, it is a Windows 10 universal application that I’m working on), the operation was too slow.
Then enters Win2D!
Thanks to it I was able to produce a method to blur my files that uses GPU and DirectX. So faster results and in the same time less battery consumption.
Even the code is pretty simple:
byte[] bytes;int width;int height;var file = await Package.Current.InstalledLocation.GetFileAsync("test.png");using (var stream = await file.OpenAsync(FileAccessMode.Read)) {BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);PixelDataProvider pixelData = await decoder.GetPixelDataAsync(); bytes = pixelData.DetachPixelData(); width = (int)decoder.PixelWidth; height = (int)decoder.PixelHeight; }var device = new CanvasDevice();var renderer = new CanvasRenderTarget(device, width, height, 72);var bitmap = CanvasBitmap.CreateFromBytes(device, bytes, width, height, DirectXPixelFormat.B8G8R8A8UIntNormalized);using (var ds = renderer.CreateDrawingSession()) {var blur = new GaussianBlurEffect(); blur.BlurAmount = 8.0f; blur.BorderMode = EffectBorderMode.Hard; blur.Optimization = EffectOptimization.Quality; blur.Source = bitmap; ds.DrawImage(blur); }var saveFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.ReplaceExisting);using (var outStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite)) {await renderer.SaveAsync(outStream, CanvasBitmapFileFormat.Png); }
So basically:
- Open the picture and use a BitmapDecoder to get bytes and dimension
- Create a canvasDevice and a CanvasRenderTarget to have offscreen rendering capabilities
- Create the effect you want to use (GaussianBlurEffect here)
- Apply the effect
- Save your file
Insanely simple, right?
Before:
After:
Win2D is a great library that you can find here: https://github.com/Microsoft/Win2D
Documentation can be found here: http://microsoft.github.io/Win2D/html/Introduction.htm
A series of posts you may find interesting about Win2D effects: http://i1.blogs.msdn.com/b/win2d/archive/2014/10/30/add-sizzle-to-your-app-with-image-effects-part-1.aspx