Quick Start for Windows Phone 8.0

Create a new project

To create a new project, follow these steps:

  1. In Visual Studio, select File > New > Project...
  2. In the New Project window, select Visual C# > Windows Phone > Windows Phone App.
  3. Press OK.
  4. Choose "Windows Phone OS 8.0" when asked. (Please note that the SDK can only be used in Windows Phone 8 projects.)

A project has now been created for you.

Include libraries to your project

Before starting to use the functionality provided by the SDK, the Lumia Imaging SDK libraries must be added to the project. For detailed instructions, please see the chapter Adding libraries to the project.

Define your XAML UI

The UI we will build for this tutorial is very simple. There will be two XAML image controls and two buttons. One XAML image control will display the original image, and the other will display the filtered image. Similarly, one button is used for selecting the image, and the other button is used for saving the filtered image to the phone library.

Dn859601.tutorial_image_01(en-us,WIN.10).png

Here are the steps to accomplish this:

  • In the Solution Explorer pane in Visual Studio, open the MainPage.xaml.
  • Our UI is in the landscape orientation. In the XAML view, search for the SupportedOrientations and shell:SystemTray.IsVisible definitions and replace it with the following:
SupportedOrientations="Landscape" Orientation="Landscape"
shell:SystemTray.IsVisible="False"
  • Add all the controls that make our UI. In the XAML view, search for the LayoutRoot grid that was generated when creating the project:
<!--ContentPanel - Place additional content here.-->
<Grid x:Name="LayoutRoot" Background="Transparent">

</Grid>
  • Replace the grid and all its content with this grid:
<!--LayoutRoot is the root grid where all page content is placed.-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Image x:Name="CartoonImage" Width="800" Height="480" Stretch="UniformToFill" Grid.RowSpan="3" />
    <Image x:Name="OriginalImage" Width="167" Height="100" Stretch="UniformToFill" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,12,0,0" />

    <TextBlock Text="Lumia Imaging SDK" Style="{StaticResource PhoneTextNormalStyle}" />

    <Button Content="Pick an image" Click="PickImage_Click" HorizontalAlignment="Left" Grid.Row="2" />
    <Button Content="Save the image" Click="SaveImage_Click" x:Name="SaveButton" HorizontalAlignment="Right" Grid.Row="2" IsEnabled="False" />

</Grid>

The only noteworthy thing in the code above is that we define the two preview images, CartoonImage and OriginalImage, without specifying any source for the image to display. We will bind the image source later; code examples will also be given in the chapters below.

Pick an image from the camera roll

Dn859601.tutorial_image_02(en-us,WIN.10).png

Next, open the MainPage.xaml.cs in the Solution Explorer pane in Visual Studio. To pick the image, we will use the PhotoChooserTask. The photo chooser is part of the Windows Phone 8 SDK.

private void PickImage_Click(object sender, RoutedEventArgs e)
{    
    SaveButton.IsEnabled = false;

    PhotoChooserTask chooser = new PhotoChooserTask();
    chooser.Completed += PickImageCallback;
    chooser.Show();
}

private async void PickImageCallback(object sender, PhotoResult e)
 {
    if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
    { 
        return;
    }
}

When the user has selected the image, the PickImageCallback is called, providing us with a System.IO.Stream that we can
use to access the content of the file. This is where we will start using the Lumia Imaging SDK.

Use FilterEffect to decode an image with an effect

Finally, we are ready to use the Lumia Imaging SDK!

Add the following using directives -- these are typically needed when using the SDK:

using System.IO;
using System.Windows.Media.Imaging;
using System.Runtime.InteropServices.WindowsRuntime;
using Lumia.Imaging;
using Lumia.InteropServices.WindowsRuntime; 

In addition to the above using directives, the following directives are used to choose an image from the photo library and to save the image into the media library.

using Microsoft.Phone.Tasks;
using Windows.Storage.Streams;
using Microsoft.Xna.Framework.Media; 

In the MainPage.xaml.cs class, declare the following member variables.

public partial class MainPage : PhoneApplicationPage

{

    // FilterEffect instance is used to apply different
        // filters to an image.
    // Here we will apply Cartoon filter to an image.
    private FilterEffect _cartoonEffect          =  null;

    // The following  WriteableBitmap contains 
    // the filtered and thumbnail images.
    private WriteableBitmap _cartoonImageBitmap      =  null;
    private WriteableBitmap _thumbnailImageBitmap    =  null;
    ...
    ...
}   

Next, we have to initialize the private members that we have just declared. We will initialize them in the constructor.

public Mainpage()
{
    InitializeComponent();

    // Initialize WriteableBitmaps to render the
        // filtered and original images.
        _cartoonImageBitmap = new WriteableBitmap((int)CartoonImage.Width, (int)CartoonImage.Height);
        _thumbnailImageBitmap = new WriteableBitmap((int)OriginalImage.Width, (int)OriginalImage.Height);
}

Once the image is selected, we can apply filters on the image. In this tutorial, we apply Cartoon filter and display the result in XAML image control (CartoonImage). The complete code of the PickImageCallback becomes:

  private async void PickImageCallback(object sender, PhotoResult e) 
  { 
    if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
    {
        return;
    }

    try
    {
        // Show the thumbnail of the original image.
        _thumbnailImageBitmap.SetSource(e.ChosenPhoto);
        OriginalImage.Source = _thumbnailImageBitmap;

        // Rewind the stream to the start.                     
        e.ChosenPhoto.Position = 0;
                        
        // A cartoon effect is initialized with  the selected image stream as the source.
        var imageStream = new StreamImageSource(e.ChosenPhoto);
        _cartoonEffect = new FilterEffect(imageStream);

        // Add the cartoon filter as the only filter for the effect.
        var cartoonFilter = new CartoonFilter();
        _cartoonEffect.Filters = new[] { cartoonFilter };

        // Render the image to a WriteableBitmap.
        var renderer = new WriteableBitmapRenderer(_cartoonEffect, _cartoonImageBitmap);
        _cartoonImageBitmap = await renderer.RenderAsync();

        // Set the rendered image as the source for the cartoon image control.
        CartoonImage.Source = _cartoonImageBitmap;
    }
    catch (Exception exception)
    {
        MessageBox.Show(exception.Message);
        return;
    }

    SaveButton.IsEnabled = true;
}

We first set the image stream from the selected image to _thumbnailImageBitmap without applying any filters to get thethumbnail of the original image.

The next line sets the position of the stream to the beginning. This step is necessary, as the current reading position of the stream will be at the end as a result of the previous step.

Next, we initialize the _cartoonEffect with the image stream (e.ChosenPhoto) of the selected image with the data coming from the JPEG file. Cartoon filter is then added to the filter list of the _cartoonEffect.

The filtered image is then rendered to the _cartoonImageBitmap using WriteableBitmapRenderer. The rendering to the _cartoonImageBitmap is asynchronous; RenderAsync replaces the image source with the current image in the _cartoonEffect.

We then enable the SaveButton, so that the filtered image could be saved.

Add capabilities

The application reads data from the Pictures folder, and therefore it needs certain capabilities.

In the Solution Explorer pane in Visual Studio, go to the Properties folder and open the WMAppManifest.xml in "View Code" mode (this can be done by right-clicking the filename).

Add the capability ID_CAP_MEDIALIB_PHOTO.

The capabilities then look something like this:

<Capabilities>
    <Capability Name="ID_CAP_NETWORKING" />
    <Capability Name="ID_CAP_MEDIALIB_AUDIO" />
    <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" />
    <Capability Name="ID_CAP_SENSORS" />
    <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
    <Capability Name="ID_CAP_MEDIALIB_PHOTO" />
</Capabilities>

Rendering and encoding to full resolution JPEG

Rendering to full resolution output JPEG is simple once we have an instance of FilterEffect. Every pixel of the original image will be processed by the library and then saved as a JPEG. The Media library is used to save the data buffer created by the SDK as a JPEG file.

This code example demonstrates how to add the functionality to save the filtered image as a full resolution JPEG:

private async void SaveImage_Click(object sender, RoutedEventArgs e)
{
    SaveButton.IsEnabled = false;

    if (_cartoonEffect == null) {
        return;
    }

    var jpegRenderer = new JpegRenderer(_cartoonEffect);
    
    // Jpeg renderer gives the raw buffer for the filtered image.
    IBuffer jpegOutput = await jpegRenderer.RenderAsync();

    // Save the image as a jpeg to the saved pictures album.
    MediaLibrary library = new MediaLibrary();
    string fileName = string.Format("CartoonImage_{0:G}", DateTime.Now);
    var picture = library.SavePicture(fileName, jpegOutput.AsStream());

    MessageBox.Show("Image saved!");

    SaveButton.IsEnabled = true;
}

Running the application

To run the application:

  1. In the standard toolbar in Visual Studio, select Device or Emulator, and then select Debug.
  2. Build the application.
  3. Connect a device (if you are deploying it on device) and run.
  4. Select an image using the Pick an image button.
  5. You should see the main page containing the decoded image with a Cartoon style filter effect added.

Tip:
If you are testing an app on an emulator, you may experience an emulator bug. If your app can't see any content in the pictures library, it is likely a result of a bug in the emulator.

If you need to access the in-built images, you need to open the photos app at least once before you begin testing your application. Once you browse through the photos, the content will become available to your app.

Get the complete source

The complete code of the tutorial: Lumia Imaging Quick Start