Posts Tagged ‘GIF’

Viewing GIF’s in Windows Phone 7

04 May

To display an image in Windows Phone 7 we are given one control to handle this, called ‘Image’.  It is very simple to use, just simply define it and load up the object with either a URI of the data source or load it with some local image data.  One glaring issue with the Image object is its not capable of displaying GIF images.

APODViewer7 had to display GIF images.  APOD’s archive was loaded with them especially from its first few years.  After those first few years GIF’s continued to be used for its animated capability.  I got it working by using the WebBrowser object.  It worked surprisingly well, it even gave me pinch to zoom and manipulation for free!  However, it required some clunkly code to make it somewhat seamless to the user.

Before I released my 2.0 version of APODViewer7 Diane Leeper did a quick run through and critique of the user experience of my development version of the application.  She gave me some great some tips on how to improve the app.  Notably, the waiting thumbnail animations and how I handle image preloading in the background. Thanks again Diane!

Diane noted other developers were struggling with this issue and that I should blog about it to inform others on how I got GIF viewing working.  That said, on to the details on how I did it.

Below are the two objects defined in XAML, an Image and WebBrowser object.  We will alternate the visibility of these objects depending on what type of image we want to load.

  1.  <Image x:Name="FullImage"/>
  3.  <phone:WebBrowser x:Name="wbViewer" Width="480" Height="696" Visibility="Collapsed" />

Three application bar buttons are defined to execute the three image loads.  Initially when the application executes nothing is rendered, pressing the application bar images loads its associated data. Pressing button 1 will render an animated GIF in the WebBrowser.  Button 2 is a JPG also loaded by the WebBrowser.  Button 3 is another JPG loaded into an Image object.  Give each call a few seconds to load, it has to download the complete image data off of the NASA web site.

When loading the GIF in the WebBrowser, we need to hide the Image object.  Then we need to create an HTML string to properly display the image.  Here is the method that formats the HTML string and loads the WebBrowser object:

  1. private void ViewImageInWebBrowser(string ImageURL)
  2. {
  3.     FullImage.Visibility = System.Windows.Visibility.Collapsed;
  5.     wbViewer.IsEnabled = true;
  6.     wbViewer.Visibility = System.Windows.Visibility.Visible;
  7.     string backgroundColor;
  9.     if (IsThemeDark() == true)
  10.     {
  11.         backgroundColor = "<body bgcolor=\"#000000\">";
  12.     }
  13.     else
  14.     {
  15.         backgroundColor = "<body bgcolor=\"#FFFFFF\">";
  16.     }
  18.     string imageHTML = "<html><head><meta name=\"viewport\" "+
  19.         "content=\"width=480\" id=\"viewport\" />" +
  20.         "</head>"+ backgroundColor + "<IMG SRC=\"" +
  21.         ImageURL + "\"></body></html>";
  23.     wbViewer.NavigateToString(imageHTML);
  24. }

Notice it initially hides the Image object and then makes the WebBrowser object visible.  The two objects are layered on top of each other, making the appropriate object visible and hiding the other. The HTML string uses a meta tag to prevent the image from being scaled incorrectly when initially rendered.  Note the IsThemeDark call.  This is used to determine how to set the WebBrowser background color based on what the user has the theme set to, light or dark. This is defined as:

  1. public static bool IsThemeDark()
  2. {
  3.     bool ThemeIsDark = false;
  5.     Color themeColor = (Color)Application.Current.Resources["PhoneForegroundColor"];
  7.     if (themeColor.ToString() == "#FFFFFFFF")
  8.     {
  9.         ThemeIsDark = true;
  10.     }
  11.     else if (themeColor.ToString() == "#DE000000")
  12.     {
  13.         ThemeIsDark = false;
  14.     }
  16.     return ThemeIsDark;
  17. }

JPG in the WebBrowser is no different then GIF’s, just a different URL loaded into the ViewImageInWebBrowser method.  Loading a JPG in an Image object is much simpler.  First we hide the WebBrowser, then create a URI of the image location and load the Image object with it.

  1. private void JPG_Image_Click(object sender, EventArgs e)
  2. {
  3.     wbViewer.IsEnabled = false;
  4.     wbViewer.Visibility = System.Windows.Visibility.Collapsed;
  6.     FullImage.Visibility = System.Windows.Visibility.Visible;
  8.     Uri u = new Uri("", UriKind.Absolute);
  9.     FullImage.Source = new BitmapImage(u);
  10. }

Some negative aspects of using WebBrowser for images is we cant directly deal with the loaded image data.   With the image object we can load image data from memory locally to the object, give it a URI to load, or extract its currently loaded data to manipulate it.  WebBrowser only allows us to load a specific HTML string using the NavigateToString method a URL using the Navigate method with no means to touch its loaded data.

There you have it, a way to display GIF’s in a WP7 app.  I admit this is rather crude, but it works and its done completely with out any external dependencies.  I have seen other solutions such as Imagetools for Silverlight that have specific calls to handle GIF’s, but I discovered this project after I implemented the above.  I’ll play around with the ImageTools to see if its worth changing APODViewer7 and blog about the differences.

If interested in the code, click here to download the complete VS2010 solution for this example.


Posted in WP7