Quickstart: Images for Windows Phone

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

In Windows Phone, you have several options for displaying images such as pictures and diagrams. This Quickstart describes how to integrate images into your Windows Phone apps.

This topic contains the following sections.

Image and ImageBrush

To display an image, you can use either the Image or the ImageBrush object. The following example shows how to display an image named licorice.jpg by using the Image object.

<Image Source="licorice.JPG" />

The following image shows the example running in the emulator.

In this example, the Source property specifies the location of the image that you want to display. You can set the Source by specifying an absolute URL (for example, https://contoso.com/myPicture.jpg) or by specifying an URL of a file that's included in the XAP file of your app. To add an image file to your app, perform the following actions in Visual Studio:

  1. On the Project menu select Add Existing Item.

  2. Select the desired image file and then click Add.

  3. In Solution Explorer, select the image file that was added.

  4. In the Properties window, change the Build Action property to Content.

When the app is built, the image file is included in the XAP.

Note

Windows Phone doesn't support all image formats. The BitmapImage class can be used to reference images in the JPEG and PNG file formats. For more information about the types of image sources and formats that can be used for an Image, see BitmapImage.

The ImageBrush object enables you to use an image to paint an area that takes a Brush object. For example, ImageBrush can be used for the value of the Background property of a Panel. For more information on brushes in Windows Phone, see the Quickstart: Brushes for Windows Phone.

The following example shows how to use the licorice image to paint the inside of some text.

<!-- TextBlock with an image brush applied to the text. -->
<TextBlock Margin="20"
    Text="LICORICE"
    FontFamily="Verdana"
    FontSize="80"
    FontWeight="Bold">
    <TextBlock.Foreground>
        <ImageBrush ImageSource="licorice.JPG"/>
    </TextBlock.Foreground>
</TextBlock>

The following image shows the example running in the emulator.

Stretching an Image

If you don't set the Width or Height values of an Image, it's displayed with the dimensions of the image specified by the Source. Setting the Width and Height creates a containing rectangular area that the image is displayed within. You can specify how the image fills this containing area by using the Stretch property. The Stretch property accepts the following values, which the Stretch enumeration defines:

  • None: The image doesn't stretch to fill the output dimensions.

  • Uniform: The image is scaled to fit the output dimensions. However, the aspect ratio of the content is preserved. This is the default value.

  • UniformToFill: The image is scaled so that it completely fills the output area, but preserves its original aspect ratio.

  • Fill: The image is scaled to fit the output dimensions. Because the content's height and width are scaled independently, the original aspect ratio of the image might not be preserved. That is, the image might be distorted to completely fill the output area.

The following illustration shows the different Stretch settings.

Cropping an Image

You can use the Clip property to crop an area from the Image output. You set the Clip property to a Geometry, which means that you can clip a variety of geometric shapes from your Image (for example, an ellipse, line, or complex path).

The following example shows how to use an EllipseGeometry as the clip region for an Image. In this example, an Image object is defined with the Source property set to an image file. An EllipseGeometry with a RadiusX value of 125, a RadiusY value of 100, and a Center value of 225,175 is set to the Clip property of the Image. Only the part of the image that is within the area of the ellipse is displayed.

<Image Source="Licorice.JPG">
    <Image.Clip>
        <EllipseGeometry RadiusX="125" RadiusY="100" Center="225,175"/>
    </Image.Clip>
</Image>

The following image shows the example running in the emulator.

Applying an OpacityMask

You can apply an OpacityMask to an Image to create a variety of opacity-related photo masking techniques, such as vignette effects.

The following example shows how to apply a radial gradient to an Image so that it fades out on the edges (vignette effect).

<Image Source="licorice.jpg" >
    <Image.OpacityMask>
        <RadialGradientBrush GradientOrigin="0.5,0.5"
            Center="0.5,0.5"
            RadiusX="0.5"
            RadiusY="0.5">
            <!-- These Gradient Stop colors are only changing the
            alpha values so the image fades out toward the edges. -->
            <GradientStop Color="#ffffffff" Offset="0.5" />
            <GradientStop Color="#00ffffff" Offset="0.8" />
        </RadialGradientBrush>
    </Image.OpacityMask>
</Image>

The following image shows the example running in the emulator.

Note

You can use a variety of Brush objects for an opacity mask. For more information on brushes in Windows Phone, see the Quickstart: Brushes for Windows Phone.

Creating WriteableBitmaps

A WriteableBitmap provides a BitmapSource that can be modified. This enables you to alter images on the fly and re-render the updated image.

You can pass a BitmapSource, the dimensions of a new bitmap, or a UIElement to the WriteableBitmap constructor. Passing in a UIElement will create a bitmap image of the visual element. For example, if you wanted a bitmap of the entire visual tree, you could pass in the root UIElement to the constructor.

The Pixels property on WriteableBitmap is an array that represents the 2D texture of the bitmap. You can alter the bitmap image by changing the pixel values in this array.

Note

The format used by the WriteableBitmap is ARGB32 (premultiplied RGB). So the pixels in the Pixel array of a WriteableBitmap are stored as pre-multiplied colors. Each color channel is pre-multiplied by the alpha value.

Note

MediaElement objects will not appear in WriteableBitmap captures. This is because MediaElement are rendered entirely in hardware on Windows Phone.

The following code sample shows how to create a WriteableBitmap image from an Image object and how to modify the WriteableBitmap. To create the WriteableBitmap, the Source property of the Image object is cast to a BitmapSource and is passed to the WriteableBitmap constructor. When the Modify Pixels button is clicked, the event handler iterates through the Pixels array of the bitmap and sets each forth pixel to black. The Image object is then set to the modified bitmap and re-rendered.

<StackPanel>
    <Image Name="ImageToModify" Source="licorice.jpg" />
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="30" >
        <Button Name="ButtonModify" Content="Modify Pixels" Click="ButtonModify_Click" />
        <Button Name="ButtonReset" Content="Reset Image" Click="ButtonReset_Click" />
    </StackPanel>
</StackPanel>
private void ButtonModify_Click(object sender, RoutedEventArgs e)
{
    int pixelTarget = 4;
    if (ImageToModify.Source != null)
    {
        // Get WriteableBitmap. ImageToModify is defined in MainPage.xaml
        WriteableBitmap bitmap =
        new WriteableBitmap(ImageToModify.Source as BitmapSource);
        // Iterate through each pixel.
        for (int x = 0; x < bitmap.Pixels.Length; x++)
        {
            // Set every 4th pixel.
            if (x % pixelTarget == 0)
            {
                bitmap.Pixels[x] = 0;
            }
        }
        // Set Image object, defined in XAML, to the modified bitmap.
        ImageToModify.Source = bitmap;
    }
}

private void ButtonReset_Click(object sender, RoutedEventArgs e)
{
    BitmapImage licoriceImage =
    new BitmapImage(new Uri("licorice.jpg", UriKind.Relative));
    ImageToModify.Source = licoriceImage;
}
Private Sub ButtonModify_Click(sender As Object, e As RoutedEventArgs)
    Dim pixelTarget As Integer = 4
    If ImageToModify.Source IsNot Nothing Then
        ' Get WriteableBitmap. ImageToModify is defined in MainPage.xaml
        Dim bitmap As New WriteableBitmap(TryCast(ImageToModify.Source, BitmapSource))
        ' Iterate through each pixel.
        For x As Integer = 0 To bitmap.Pixels.Length - 1
            ' Set every 4th pixel.
            If x Mod pixelTarget = 0 Then
                bitmap.Pixels(x) = 0
            End If
        Next
        ' Set Image object, defined in XAML, to the modified bitmap.
        ImageToModify.Source = bitmap
    End If
End Sub

Private Sub ButtonReset_Click(sender As Object, e As RoutedEventArgs)
    Dim licoriceImage As New BitmapImage(New Uri("licorice.jpg", UriKind.Relative))
    ImageToModify.Source = licoriceImage
End Sub

Reducing resource usage and improving performance

When you use a BitmapImage as the Source of the Image, you gain additional control over the image’s resource requirements and performance.

To load an image at reduced size, set the image's DecodePixelWidth and DecodePixelHeight properties before loading it. When you don't use these properties, the application consumes unnecessary resources by caching the image at its original size and not at the smaller size that is displayed. To preserve aspect ratio, set one of these properties but not both.

To improve performance, specify BackgroundCreation to decode the image on a background thread instead of blocking the UI thread.

See Also

Other Resources

Quickstart: Shapes for Windows Phone

Quickstart: Brushes for Windows Phone