Quick Start for Windows
Create a new project
To create a new project, follow these steps:
- In Visual Studio, click File > New > Project...
- In the New Project window, select Other Languages > Visual Basic > Windows > Universal > Blank App (Universal Windows).
- Click OK.
A project has now been created for you.
Include libraries to your project
Before you start to use the functionality provided by the SDK, the Lumia Imaging SDK libraries must be added to the project. For detailed instructions, 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 one is used for saving the filtered image to the phone library.
Here are the steps to accomplish this:
- Move MainPage.xaml and MainPage.xaml.vb to the QuickStart.Shared project to share as much as possible, even the UI.
- In the Solution Explorer pane in Visual Studio, open MainPage.xaml.
- Add all the controls that make our UI. In the XAML view, search for the layout root grid that was generated when creating the project:
<Grid>
</Grid>
Replace the grid and all its content with this grid:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Quick Start" Margin="4,4,0,4" FontSize="32"></TextBlock>
<StackPanel Grid.Row="1">
<SwapChainPanel x:Name="SwapChainPanelTarget" Grid.Row="1" Width="500" Height="500"/>
<TextBlock Text="Brightness" Margin="20,0,0,0"/>
<Slider Minimum="-1.0" Maximum="1.0" StepFrequency="0.1" ValueChanged="OnBrightnessChanged" Margin="20,0" ></Slider>
</StackPanel>
<Image x:Name="OriginalImage" Grid.Row="1" Width="200" Height="200" Stretch="Uniform"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,12,0,0" />
<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>
In the preceding snippet, we define the preview images, one OriginalImage and one SwapChainPanel SwapChainPanelTarget, 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
To pick the image, we will use the FileOpenPicker, which is part of the SDK.
Next, open MainPage.xaml.vb to add the code to pick the image and save the image.
Private Sub PickImage_Click(sender As Object, e As RoutedEventArgs)
Dim openPicker = New FileOpenPicker()
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
openPicker.ViewMode = PickerViewMode.Thumbnail
' Filter to include a sample subset of file types.
openPicker.FileTypeFilter.Clear()
openPicker.FileTypeFilter.Add(".bmp")
openPicker.FileTypeFilter.Add(".png")
openPicker.FileTypeFilter.Add(".jpeg")
openPicker.FileTypeFilter.Add(".jpg")
PickImage(openPicker)
End Sub
Note the last call to PickImage, which does not exist yet, but will be added to a specific partial implementation for each platform.
Private Sub SaveImage_Click(sender As Object, e As RoutedEventArgs) Handles SaveButton.Click
SaveButton.IsEnabled = False
Dim savePicker = New FileSavePicker()
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
savePicker.SuggestedFileName = String.Format("QuickstartImage_{0}", DateTime.Now.ToString("yyyyMMddHHmmss"))
savePicker.FileTypeChoices.Add("JPG File", New List(Of String)() From {".jpg"})
SaveImage(savePicker)
SaveButton.IsEnabled = False
End Sub
Note the last call to SaveImage, which does not exist yet, but will be added to a specific partial implementation for each platform.
Now, create a new class in each platform project, for example, MainPage.cs
Add the following code:
Private Async Sub PickImage(openPicker As FileOpenPicker)
' Open the file picker.
Dim file As StorageFile = Await openPicker.PickSingleFileAsync()
' file is null if user cancels the file picker.
If file IsNot Nothing Then
If Not (Await ApplyEffectAsync(file)) Then
Return
End If
SaveButton.IsEnabled = True
End If
End Sub
Private Async Sub SaveImage(savePicker As FileSavePicker)
Dim file = Await savePicker.PickSaveFileAsync()
If file IsNot Nothing Then
Await SaveImageAsync(file)
End If
SaveButton.IsEnabled = True
End Sub
Now, we are ready to start using the Lumia Imaging SDK.
Add the following using directives:
Imports Lumia.Imaging
Imports Lumia.Imaging.Adjustments
Imports Windows.Storage
Imports Windows.Storage.Pickers
Imports Windows.Storage.Streams
Imports Windows.UI.Popups
In the MainPage.xaml.vb class, declare the following member variables.
Public NotInheritable Class MainPage
Inherits Page
Private _grayscaleEffect As GrayscaleEffect
Private _brightnessEffect As BrightnessEffect
Private m_renderer As SwapChainPanelRenderer
' The following WriteableBitmap contains
' The filtered and thumbnail image.
Private _writeableBitmap As WriteableBitmap
Private _thumbnailImageBitmap As WriteableBitmap
Next, we have to initialize the private members that we have just declared. We will initialize them in the constructor.
The **_grayscaleEffect** will be the ImageProvider to the Brightness effect. We also create the SwapChainPanelRenderer with the Brightness effect as ImageProvider.
Public Sub New()
InitializeComponent()
Dim scaleFactor As Double = 1.0
scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel
_writeableBitmap = New WriteableBitmap(CInt(Window.Current.Bounds.Width * scaleFactor), CInt(Window.Current.Bounds.Height * scaleFactor))
_thumbnailImageBitmap = New WriteableBitmap(CInt(OriginalImage.Width), CInt(OriginalImage.Height))
_grayscaleEffect = New GrayscaleEffect()
_brightnessEffect = New BrightnessEffect(_grayscaleEffect)
m_renderer = New SwapChainPanelRenderer(_brightnessEffect, SwapChainPanelTarget)
LoadDefaultImageAsync()
End Sub
Private Async Sub LoadDefaultImageAsync()
Dim file = Await StorageFile.GetFileFromApplicationUriAsync(New System.Uri("ms-appx:///Assets/defaultImage.jpg"))
Await ApplyEffectAsync(file)
End Sub
Once the image is selected, we can apply the effect on the image. In this tutorial, we apply the Grayscale effect, which is combined with the Brightness effect, and display the result in XAML SwapChainPanel control (SwapChainPanelTarget). The complete code of the ApplyEffectAsync method becomes:
Private Async Function ApplyEffectAsync(file As StorageFile) As Task(Of Boolean)
' Open a stream for the selected file.
Dim fileStream As IRandomAccessStream = Await file.OpenAsync(FileAccessMode.Read)
Dim errorMessage As String = Nothing
Try
' Show thumbnail of original image.
_thumbnailImageBitmap.SetSource(fileStream)
OriginalImage.Source = _thumbnailImageBitmap
' Rewind stream to start.
fileStream.Seek(0)
' Set the imageSource on the effect and render
DirectCast(_grayscaleEffect, IImageConsumer).Source = New Lumia.Imaging.RandomAccessStreamImageSource(fileStream)
Await m_renderer.RenderAsync()
Catch exception As Exception
errorMessage = exception.Message
End Try
If Not String.IsNullOrEmpty(errorMessage) Then
Dim dialog = New MessageDialog(errorMessage)
Await dialog.ShowAsync()
Return False
End If
Return True
End Function
First, we set the image stream from the selected image to **_thumbnailImageBitmap** without applying any effect to get the thumbnail of the original image. The next line resets 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 create a RandomAccessStreamImageSource with the selected file, and set the source on the **_grayscaleEffect**.
The filtered image is then rendered to the SwapChainPanelTarget.
Add capabilities
Because the application reads data from the Pictures folder, it
needs certain capabilities. In the Solution Explorer pane in Visual Studio,
open the Package.appxmanifest and open the Capabilities tab. Make
sure that the Pictures Library capability is checked.
Rendering and encoding to full resolution JPEG
Rendering to a full resolution output JPEG is simple once we have an
instance of GrayScaleEffect. Every pixel of the original image will be
processed by the library and then saved as a JPEG.
This code example demonstrates how to add the functionality to save the
filtered image as a full resolution JPEG:
private async Task<bool> SaveImageAsync(StorageFile file)
{
if (_grayscaleEffect == null)
{
return false;
}
string errorMessage = null;
try
{
using (var jpegRenderer = new JpegRenderer(_grayscaleEffect))
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
// Jpeg renderer gives the raw buffer that contains the filtered image.
IBuffer jpegBuffer = await jpegRenderer.RenderAsync();
await stream.WriteAsync(jpegBuffer);
await stream.FlushAsync();
}
}
catch (Exception exception)
{
errorMessage = exception.Message;
}
if (!string.IsNullOrEmpty(errorMessage))
{
var dialog = new MessageDialog(errorMessage);
await dialog.ShowAsync();
return false;
}
return true;
}
Running the application
To run the application:
- In the standard toolbar in Visual Studio, select Device or Emulator, and then select Debug.
- Build the application.
- Connect a device (if you are deploying it on device) and run the application.
- Select an image using the Pick an image button.
- You should see the main page that contains the decoded image with a Cartoon style 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 built-in 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.
Check out the project in GitHub
Check out our open source project Lumia Imaging SDK in GitHub: Lumia Imaging SDK Git repository
Or get the complete source code of the tutorial: Lumia Imaging Quick Start