Innovate with Silverlight 2

«One of the reasons we pick up a new technology is the power it gives us to bring better experiences to our customers, clients, and users.» - Daniel Crenna

Silverlight can help you build rich, interactive user experiences using skills you already have. Daniel Crenna shows us how to create an in-browser image editing component that provides a seamless experience within a web application.

One of the reasons we pick up a new technology is the power it gives us to bring better experiences to our customers, clients, and users. If you’re excited about a new way to get the job done, there’s value in that, but when you can connect that excitement with the people who rely on your work to get their jobs done, then you really have something worth talking about.

Silverlight 2 is approaching its final release. As Microsoft’s latest technology for enabling rich interactive experiences on the web, it provides developers a way to use our existing .NET development skills to deliver more to our users than they expect, in the form of enhanced media, graphics, animation, and design capabilities. As a web developer you’re already building great experiences today using ASP.NET, so the focus of this article is to solve one of your daily challenges working in ASP.NET in an effective way with Silverlight 2 that gives a better experience for your users.

The challenge

If you build ASP.NET web applications today that allow users to upload photos, you know that it’s a process of posting back file content, manipulating it on the server, and, if necessary, sending the image back to the user after each request. If you want to give your users the ability to interact with that image in the browser, then you’ll face another challenge in leveraging a client-side scripting language to provide the wizardry that makes your images come to life.

Often your server pays the price, since photos must be uploaded in their entirety to the server before you can take steps to resize or compress the image sufficiently to ease the size of your database storage (and these days, nearly everyone I know owns at least a ten megapixel camera). Of course, you can impose restrictions on file sizes or provide instructions for your users to crop their images, but you can do better. Silverlight 2 can make the image manipulation story one you can get excited about.

Imagine an application...

Let’s think about an application that provides an end-to-end that makes good use of images: a bug tracking application. With this application, a user can spot an issue with a web site, take a screen capture of the problem, and upload it for further analysis. With Silverlight 2 we can provide the user with an interactive experience in which they upload their photo to a Silverlight control, crop the interesting region, and then send the cropped image to the server. You win because only the relevant information is sent to the server, saving bandwidth, and the users win because they don’t need any special software or knowledge outside of your bug tracker to get the job done.

Here’s what our bug tracking image component might look like:

Our application has an area to display the working image, and a preview of the cropped selection. The user can click and drag over the working image to define the cropping region.

In with the new but let’s keep the old, too

If you want to use Silverlight without throwing away your existing ASP.NET web applications, the good news is that Silverlight can live snugly within an ASP.NET form. This means we can wrap our existing applications around one or several XAML controls that we build in Silverlight. For example, we might decide to use our image component within an ASP.NET page:

You are free to incorporate one or many Silverlight controls in your existing ASP.NET markup. In this example the image cropping component fits neatly within a traditional page layout.

Working with Silverlight 2

To build our application, we’ll use XAML, which is a markup language similar to HTML that lets us define our interface. As an example, here is the XAML markup for the main canvas which displays the working image above.

XAML gives us an expressive way to define how our application will appear.

As you can see, the thick black border around the working area is defined as a Border element, and the CornerRadius property is responsible for the rounded corners. Inside the ‘canvas’ element we add an Image control which we can use to display our working image. A similar XAML snippet will define the “picture in picture” preview you see in the application.

Working with Buttons and Events in Silverlight 2 is similar to ASP.NET. You can declare your event handlers, either in XAML or in code-behind, to configure application behavior. In this case we’ve declared an upload button that will use Silverlight’s OpenFileDialog class to select a supported image on the client’s computer, open it, and obtain a stream for the selected image. We’ll use this stream to display our image in the main form and in the “picture-in-picture” preview area. Silverlight allows immediate use of a user’s files using streams, creating opportunities for working with client-side files not previously possible in ASP.NET.

Imagine an interface...

Another nice aspect of Silverlight application development is that we can program against a stateful, persistent UI that simple ‘behaves’, rather than a UI whose client-side updates require asynchronous feedback to the server (as is the case with ASP.NET AJAX applications) and partial page refreshes to achieve a smooth, snappy experience. This means that to design the interactive cropping region that a user can click and drag around the image, all we need to do is define its appearance in XAML or in code-behind, and change its properties (such as width, height, and location) in order to see those changes come alive in our application. This also means you can perform powerful data-binding scenarios in which you bind your UI elements to values that change in real-time.

Here we’re creating a new Rectangle visual element in code-behind and adding event handlers to mouse actions that occur within the main image control. Changing the properties of the ‘_cropBox’ element in response to mouse events is all that’s required to achieve an interactive region selection feature that would be difficult to duplicate in ASP.NET.

Images in Silverlight

Silverlight 2 is designed with a focus on user experience. One aspect of that experience is the size of the Silverlight 2 runtime itself. In order to provide a fast and lean installation for users, many of the classes you’re accustomed to using in .NET and Windows Presentation Foundation (WPF) aren’t present in Silverlight. Included in this list are the encoder and decoder classes for image formats like JPEG, PNG, GIF, and BMP.

This means that while Silverlight can effortlessly display PNG and JPEG images that the user selects via the OpenFileDialog control, it cannot decode the images into the usable data you need to manipulate them. Fortunately Silverlight is built on a foundation of .NET, which means that whatever functionality we might need for our applications, we can provide our own code to bridge the gap and get the job done. In our case, we’re going to draw from a wide variety of community contributions to put together an imaging library that will allow us to easily work with JPEG, PNG, GIF, and BMP files directly in the client application.

Imaging 101

A photo stored in an image format like JPEG is really nothing more than a bunch of bytes that describe the color information, or the color of each pixel in the image. To save space on disk, image formats are compressed, similar to how ASP.NET can compress static resources like CSS and JavaScript files using the .NET 2.0 GZipStream or DeflateStream classes.

Every pixel color is made up of a combination of values representing the amount of red, green, blue, and alpha, or opacity values. Commonly referred to as RGB, every pixel in an image has all four of these values. As a simple example, an array of bytes that we’ve obtained from a file stream to a JPEG image, and have successfully decoded, might look like this:

[125, 17, 8, 255, 14, 12, 19, 255, 20, 55, 77, 255 …]

But what it really means behind the scenes is this:
[R, G, B, A, R, G, B, A, R, G, B, A …]

This decoded array is very useful because it contains the color information for each pixel in our image. With this information we can reconstruct the image, crop a smaller section of it, apply a filter, or do anything else we desire. Our goal for this application, then, is to take a regular, encoded JPEG, PNG, GIF, or BMP file from a stream we open in Silverlight 2, and translate it into bytes we can manipulate in code.

A community of help

Fortunately, there is an active and vibrant open source community in .NET that we can call upon to solve our challenges. Imaging is a specialized field, which means there are many people who dedicate their careers to producing useful work in imaging for others [1]. While we can certainly learn how image formats work in depth, our real goal is to produce great web applications.

To make use of client-side imaging in Silverlight we’re going to draw from several sources to make it happen. One of those sources is Joe Stegman, Group Program Manager of the Silverlight presentation and graphics team. Joe has posted several examples for dynamic image generation in Silverlight[2], several of which we use in our application to provide BMP and GIF decoding support, as well as the ClientImage class that we can interact with to work with decoded images.

We'll still need to provide JPEG and PNG support if we want to round out our image offering and not restrict the user in what kinds of images our application can handle. JPEG support is available from the talented team at Occiptal.com, whose “fluxify” image application allows users to resize JPEG photos on the fly in their browser using Silverlight [3]. They’ve released the source code for their JPEG decoder, which just leaves PNG support to make our application really shine. Thanks to another open source library, this capability is also part of our cropping application.

Conclusion

If you build web applications, Silverlight can help you build rich, interactive user experiences using skills you already have. You can build Silverlight components that work within your existing ASP.NET applications or build an entire application from the ground up. In this example, we saw how Silverlight makes it possible to implement an image editing feature that is a win for both you and your users: you save server bandwidth by cropping images directly on the client, and users gain a seamless experience working with images within your application. There is a growing developer community around Silverlight and plenty of resources available for you to go even further and discover new ways to impress. Go find out what’s possible!

Source code

You can download the full source code for this article here, which goes further to demonstrate the following concepts which you can put to use in your Silverlight applications that use images:

  • How to upload images from Silverlight to your ASP.NET server using a WCF service
  • How to store the decoded working image in Isolated Storage, a persistent user state capability familiar to .NET Windows client developers

Note: To use the solution, you’ll need to install Visual Studio 2008 Standard edition or higher, as well as Silverlight Tools Beta 2 for Visual Studio 2008. You can learn more about these pre-requisites here. Choose ‘PhotoCropper.aspx’ as your startup page in the ‘PhotoCropperWeb’ web application project within the solution.

Have fun!

References

[1] If you’re interested in writing your own image format encoders, like fluxcapacity.net did for JPEG images, you can find a wealth of information online on how each image format is constructed. For example, the JPEG format is described in detail here.

[2] Joe Stegman’s blog has several useful posts with full source code, including an EditableImage class that represents decoded or created images you can manipulate directly, as well as example BMP and GIF decoders.

[3] fluxify is a great example of client-side image editing in Silverlight 2. Similar to this example, it allows a user to upload a JPEG image and select a pre-defined size, performing all the work on the client side. It is also a good example of the kind of rich interfaces we can build in Silverlight. Check it out here

Licenses and Attributions PNG Decoder:

Based on the sharppng pr2.code project

Under the Lesser General Public License

Under the MIT License

PNG Encoder:

Based on the examples written by Joe Stegman

GIF Decoder:

Based on the examples written by Joe Stegman

Derived from the 'GifUtility' project here

Copyright (c) 2008, jillzhang All rights reserved.

Under the New BSD License

BMP Decoder:

Based on the examples written by Joe Stegman, provided here.

JPG Decoder:

Copyright (c) 2008 Jeffrey Powers for Fluxcapacity Open Source. Under the MIT License.

About Daniel Crenna

Daniel Crenna is a developer for T4G, a Microsoft Gold Certified Partner. He is passionate about web development and works with ASP.NET AJAX, LINQ, and Silverlight technologies. He runs the Dev East (Halifax) user group, is a contributor on the ASP.NET AJAX Control Toolkit team, and hopes you’ll like the Backlight project. You can read his blog here.


© 2009 Microsoft Corporation. All rights reserved.  Terms of Use | Trademarks | Privacy Statement