Loading and processing bitmaps

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

Here's code that will allow the user to select an image using a FilePicker control, and then load and process it.

Windows 8 provides you with FilePicker controls to allow your users to quickly select files: for example, images.

Note  Apps written for Windows Phone 8.1 should use PickSingleFileAndContinue rather than PickSingleFileAsync. Using this API requires some extra steps, see How to continue your Windows Phone app after calling a file picker (Windows Phone Store apps using C#/VB/C++ and XAML).

 

In this short C# code sample, the user can use the FilePicker control to select an image file and then we'll display it in our app. The only assumption we'll make is that your app already has a XAML <Image> control, and you've named it myImage. Here's the code:

async private void LoadImage()
        {
            // Load an image

             Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();

                 openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
                 openPicker.ViewMode = Windows.Storage.Pickers.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");

                // Open the file picker.
                Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();

                // file is null if user cancels the file picker.
                if (file != null)
                {
                    // Open a stream for the selected file.
                    Windows.Storage.Streams.IRandomAccessStream fileStream =
                        await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

                    // Set the image source to the selected bitmap.
                    Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
                        new Windows.UI.Xaml.Media.Imaging.BitmapImage();

                    bitmapImage.SetSource(fileStream);
                    myImage.Source = bitmapImage;
                    this.DataContext = file;

                }
            }

Note  As this code is using the await keyword to load the file asynchronously, it needs to be in a method declared as async private. For more info, see Quickstart: Calling asynchronous APIs in C# or Visual Basic.

 

Image processing and bitmaps

Loading and displaying a bitmap is good, processing the bitmap is better. This code follows on from the example above, using the file object to gain access to a stream, and then accessing the raw pixel data of the image. A new WritableBitmap image is created using this raw data, and then the colors are manipulated before it is displayed once more.

Note  It is important to add using System.Runtime.InteropServices.WindowsRuntime; or the code will not compile.

 

               // Add: using Windows.UI.Xaml.Media.Imaging;
                // Add: using System.Runtime.InteropServices.WindowsRuntime;

                int height = bitmapImage.PixelHeight;
                int width = bitmapImage.PixelWidth;

                using (var stream = await file.OpenReadAsync())
                {
                    WriteableBitmap bitmap = new WriteableBitmap(width, height);
                    await bitmap.SetSourceAsync(stream);

                    using (var buffer = bitmap.PixelBuffer.AsStream())
                    {
                        Byte[] pixels = new Byte[4 * width * height];
                        buffer.Read(pixels, 0, pixels.Length);

                        for (int x = 0; x < width; x++)
                        {

                            for (int y = 0; y < height; y++)
                            {
                                int index = ((y * width) + x) * 4;

                                Byte b = pixels[index + 0];
                                Byte g = pixels[index + 1];
                                Byte r = pixels[index + 2];
                                Byte a = pixels[index + 3];

                                // Some simple color manipulation
                                byte newB = (Byte)((r + g) / 2);
                                byte newG = (Byte)((r + b) / 2);
                                byte newR = (Byte)((b + g) / 2);

                                pixels[index + 0] = newB;
                                pixels[index + 1] = newG;
                                pixels[index + 2] = newR;
                                pixels[index + 3] = a;
                            }
                        }

                        buffer.Position = 0;
                        buffer.Write(pixels, 0, pixels.Length);
                        myImage.Source = bitmap;
                    }
                }

Note  If you plan on processing the same WriteableBitmap multiple times, make a call to WritableBitmap.Invalidate() each time.

 

Topics for iOS devs

Resources for iOS devs

Windows 8 controls for iOS devs

Windows 8 cookbook for iOS devs

File pickers and bitmap topics

Guidelines for file pickers(Windows Store apps)

Part 4: File access and pickers

WriteableBitmap.PixelBuffer property