1. Working with Images on Windows Phone 7
Windows Phone 7 supports BMP, TIF, GIF, JPEG, and PNG
formats in general. However, from a development perspective JPG and PNG
are supported for viewing in the Silverlight Image control. The JPG and
PNG formats are recommended for displaying images within an
application. JPG is preferred when the image will remain opaque. The PNG
format supports transparency and is preferred for this scenario.
1.1. Images Classes
The Image control is the Silverlight class
for displaying images in applications. A related Silverlight object that
us very useful is the ImageBrush object. As an example, setting the background on a Panorama object is via an ImageBrush like this:
<controls:Panorama.Background>
<ImageBrush ImageSource="PanoramaBackground.jpg" Opacity="0.785" />
</controls:Panorama.Background>
Note that for the Opacity value to have an effect with an ImageBrush object, the image pointed to via the ImageSource property must be a .PNG file.
The BitmapImage is the utility class that provides the class for the Image.Source property. The BitmapImage supports the JPEG and PNG format. The BitmapImage has two constructors, one that takes a URI and the other that takes a Stream. You can set Image.Source via a BitmapImage without having to save the file to disk, which is better for performance.
The WriteableBitmap class is a versatile class that provides a BitmapSource that can be written to and updated. The WriteableBitmap class has properties to retrieve DPI, Format, Metadata, Palette, and Pixel size. The WriteableBitmap class provides methods to CopyPixels and to WritePixels into the WriteableBitmap. It is possible to generate an image within your application using the WriteableBitmap's constructor that takes a UIElement:
WriteableBitmap bmp =
new WriteableBitmap(element, transform)
The WriteableBitmap class allows you to
generate images on the client when needed. One example would be if you
need to add branding to an image or somehow modify it before rendering,
such as when creating a music+video hub application.
This is a short section
highlighting key classes, properties, and capabilities when working with
images. These classes are leveraged in the next couple of sections
including the next section that demonstrates how to work with the media
library on Windows Phone 7.
2. The Windows Phone 7 Media Library
The MediaLibrary class provides access to
the media available on the device as part of the music+video hub and
corresponding Zune service. So if a user rips their CD collection,
purchases some music from Zune, and so on, and the content is available
in the music+video hub on the device, the MediaLibrary class
provides the ability to enumerate and index the content but you cannot
add media content to the Media Library except for images, which can be
added to the Pictures collection. If you download audio or video content
in your application you can only save it to your application's isolated
storage area.
The MediaLibrary class does not provide
access to media content stored in individual third-party application's
isolated storage area. Here is a list of the available media collections
on Windows Phone 7:
Albums: AlbumCollection class
Artists: ArtistCollection class
Genres: GenreCollection class
Pictures: PictureCollection class
Playlists: PlaylistCollection class
Songs: SongCollection class
To gain access to the MediaLibrary class add a reference to the Microsoft.Xna.Framework assembly. The MediaLibrary
class was originally available as part of the XNA Game Studio
development environment for the Zune music player, and that is how it is
made available on Windows Phone 7. Add a using clause for the Microsoft.Xna.Framework.Media namespace to get started.
NOTE
To run this sample while debugging, shutdown Zune
and run the WPConnect.exe tool from a command-line to enable debugging
when accessing media content on a physical device.
The project is once again based on the MVVM
Light SDK and data bound to the UI. This time we use a Panorama control as the main page with a background based on a photo from a recent vacation. There are four PanoramaItem panels:
Albums
Artists
Playlists
Songs
Each PanoramaItem includes a ListBox
that data binds to a collection of these items. You might be tempted to
do something like this for making the media available to the UI:
public AlbumCollection Albums
{
get { return _mediaLibrary.Albums; }
}
Data binding to this property does not return any
data. This is because there could be many artists, albums, and songs in a
collection. Instead you must access each item via indexed access into
the collection. To make the media items available, declare properties of
type List<Album>, and so on, for each property just like with
other samples.
The interesting aspect to this code sample is the method call that loads the data as shown in Listing 1.
Example 1. MainViwModelMethod that Populates the Media Collections
private void CreateDataCollections()
{
Albums = new List<Album>();
Album album = null;
for (int i = 0; i < _mediaLibrary.Albums.Count;i++)
{
album = _mediaLibrary.Albums[i];
Albums.Add(album);
}
Artists = new List<Artist>();
Artist artist = null;
for (int i = 0; i < _mediaLibrary.Artists.Count; i++)
{
artist = _mediaLibrary.Artists[i];
Artists.Add(artist);
}
Songs = new List<Song>();
Song song = null;
for (int i = 0; i < _mediaLibrary.Songs.Count; i++)
{
song = _mediaLibrary.Songs[i];
Songs.Add(song);
}
Playlists = new List<Playlist>();
Playlist playlist = null;
for (int i = 0; i < _mediaLibrary.Playlists.Count; i++)
{
playlist = _mediaLibrary.Playlists[i];
Playlists.Add(playlist);
}
}
|
You must access the media item by index into a local variable and then add it to the List<Artist> collections, as shown in Listing 1,
for each media type in order to have an actual object reference. Note
that adding the entire collection as in the sample can be risky from a
memory consumption standpoint if the user has a large media collection.
The MediaLibrary.Albums collection has a reference to album art available but it is not directly published as a property on the Album object. The Album object does have a HaveArt property with a GetAlbumArt method. Remember from the previous sample that IValueConverter data converters allow you to data bind to anything. For this sample a simple data converter that creates a BitmapImage object to hold the image returned by the Album.GetAlbumArt() method call. The BitmapImage is then returned as the value for the Image.Source property to display the album art. Listing 2 shows the data converter.
Example 2. AlbumArtConverter Code File
using System;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Media;
namespace WorkingWithMediaLibrary.Converters
{
public class AlbumArtConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
try
{
BitmapImage artImage = new BitmapImage();
Album album = value as Album;
if (album.HasArt)
{
artImage.SetSource(album.GetAlbumArt());
}
return artImage;
}
catch (Exception err)
{
return "";
}
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
|
The last item to cover is that you can play songs or SongCollection objects via the MediaPlayer.Play() method, which is covered in more detail below. Figure 1
shows the UI in the emulator, which has just test data for a single
album and a few songs so you will want to run on a real device with a
populated library.
This concludes our coverage
of the Windows Phone 7 media library programmable API. Next up is how to
create a Photo Extras application.