Over a million developers have joined DZone.

GIF to JPEG for Windows Phone 7 - via a WCF service

· Mobile Zone

Learn how to Deliver Better Mobile Apps Faster with Continuous Quality by managing the complexities of testing multiple devices and scenarios with this whitepaper from Perfecto Mobile.

As you probably know, Windows Phone 7 application development is mainly based on Silverlight, and Silverlight doesn’t support GIF images. That is fine, unless a web API you are using exposes some of its data through GIF images, and you don’t have much control over the API engine.

To be specific, I was experimenting with a WP 7 application, that accesses the Google Weather API. The XML data that is returned by an API call is fully readable, but one element that can also be used in the application is the graphic representation of the current condition. And unless you want to bundle an entire set of your own icons that will represent each separate condition (this is not a decent choice for a Windows Phone 7 application, where resources are limited), you need to use the images provided by the API. The problem is that the images are in GIF format:

image

Initially, I thought about performing the image conversion directly in the application, but this would require more resources to be used and in case with a phone, where every percent of CPU load and every megabyte of RAM counts, I decided that it would be reasonable to delegate this task to a web service.

Here is how I did this. First of all, create a WCF service application in Visual Studio:

image

By default, you will get some basic structures created for you. This will be a default interface and a couple of methods.

image

Since I am going to use pretty much the same structure, I am simply going to add functionality to existing classes. First of all, I modified my service interface:

[ServiceContract]
public interface IConverter
{
[OperationContract]
byte[] ConvertGifToJpeg(byte[] content);
} 

The only method available through this service will get the byte array for the downloaded GIF image and convert it to JPEG. Therefore, it accepts a byte array as a parameter and returns a byte array.

The actual method was inspired from this post by Peter Bromberg. I introduced some modifications to the helper method to take advantage of LINQ instead of having a separate foreach loop. The modified service interface looks like this:

public class Service1 : IConverter
{
public byte[] ConvertGifToJpeg(byte[] content)
{
Bitmap bitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(content));
MemoryStream stream = new MemoryStream();
ImageCodecInfo info = GetCodecInfo("image/jpeg");
EncoderParameters parameters = new EncoderParameters(3);
parameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW);
parameters.Param[1] = new EncoderParameter(Encoder.Quality, 100L);
parameters.Param[2] = new EncoderParameter(Encoder.ColorDepth, 24L);
bitmap.Save(stream, info, parameters);
return stream.GetBuffer();
}
private static ImageCodecInfo GetCodecInfo(string MIME)

ImageCodecInfo codecInfo = (from c in ImageCodecInfo.GetImageEncoders() where c.MimeType == MIME select c).First();
return codecInfo;
}
}

It simply save the existing array with LZW compression with minimal quality loss. Basically, this is the core of the service, but it needs to be pre-registered before accessing it from a Windows Phone 7 Silverlight application. Run the service so that the WCF Test Client is launched (done by pressing F5 while in the main service code file).

image

You can see that the service was registered and there is now a dedicated service URL. Now you can add a service reference to the WP7 application.

Right click on References in Solution Explorer and select Add Service Reference.

image

Add the service URL to the service list, and if it is accessible (make sure there is no firewall that can block specific ports), you will see your service listed as one of the available reference points:

image

Once you add the reference, make sure the service is launched. In your Windows Phone 7 application, you should first of all create an instance of the current service class.

ServiceReference1.ConverterClient client = new ServiceReference1.ConverterClient(); 

 

The method will be invoked asynchronously (the async procedures are created automatically for the WCF service), so you need to add a reference to the ConvertGifToJpegCompleted event handler:

client.ConvertGifToJpegCompleted += new EventHandler<ServiceReference1.ConvertGifToJpegCompletedEventArgs>(client_ConvertGifToJpegCompleted); 

 

This way you can read the content while the main thread is responsive.

void client_ConvertGifToJpegCompleted(object sender, ServiceReference1.ConvertGifToJpegCompletedEventArgs e)
{
using (MemoryStream stream = new MemoryStream(e.Result))
{
BitmapImage image = new BitmapImage();
image.SetSource(stream);
}
} 

A simple call to ConvertGifToJpegAsync will trigger the event handler:

client.ConvertGifToJpegAsync(imageContents);

 

Where imageContents is the byte array for the GIF image. The result is pretty good-looking (following the same Google Weather API example):

image

It is a neat workaround. Generally, you won’t encounter GIF images really often since PNG is pretty much taking over that domain. Notice that I am not talking about animated GIFs – since it is converted to JPEG, obviously any animation present will be lost.

Do you know Why Apps Succeed? Perfecto Mobile analyzed over 1,000 responses to their Digial Quality Strategies survey and aim to answer the question, "Why do apps succeed?" in this exclusive report.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}