How to get pixel data in a particular format (XAML)
[ 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 ]
We show you how to use a BitmapDecoder object to get pixel data from an image. The pixels are packaged as a byte array and you can specify the format when you request the data.
You can specify these attributes of the pixel data that BitmapDecoder produces:
- The pixel format (BitmapPixelFormat).
- The alpha mode (BitmapAlphaMode).
- A flip, rotate, scale and/or crop operation (BitmapTransform).
- Whether to respect an embedded EXIF orientation flag (ExifOrientationMode).
- Whether to perform color management to the sRGB color space (ColorManagementMode).
This is useful if you need fine control over decoding behavior or if your app expects pixel data to be in a particular format. For example, if you are interoperating with the HTML Canvas Context2D API, you must provide pixel data as Rgba8 and straight alpha.
What you need to know
Technologies
Prerequisites
- We assume you know how to create a basic Windows Runtime app using C++, C#, or Visual Basic. For more info, see Create a "Hello, world" app (XAML).
- You have a BitmapDecoder object. How to decode an image walks you through that process.
Instructions
Step 1: Get a decoder object
Write the beginning a function that receives a BitmapDecoder object.
async void GetPixelData(Windows.Graphics.Imaging.BitmapDecoder decoder)
{
The decoder lets you access the pixel data. If you don't have a decoder object yet, see How to decode an image.
Step 2: Get a pixel data provider object
Call the GetPixelDataAsync method and specify parameters to control the format of the returned pixel data. The pixel data provider contains the pixel data in the format you specify. When GetPixelDataAsync returns, the pixel data is allocated and ready use.
var pixelProvider = await decoder.GetPixelDataAsync(
Windows.Graphics.Imaging.BitmapPixelFormat.Rgba8,
Windows.Graphics.Imaging.BitmapAlphaMode.Straight,
new Windows.Graphics.Imaging.BitmapTransform(),
Windows.Graphics.Imaging.ExifOrientationMode.RespectExifOrientation,
Windows.Graphics.Imaging.ColorManagementMode.ColorManageToSRgb
);
In this case, we set the pixel format to RGBA8 and the alpha mode to straight. When the pixel data is returned, the handling code works based on this assumption. We don't apply any transforms except to respect EXIF orientation and enable color management.
Note You can call GetPixelDataAsync with no arguments, The method then returns the pixel data in the original format. See How to get pixel data in the default format for more info.
Step 3: Get the pixels from the data provider
Call the DetachPixelData method to get a byte array of the pixel data.
var pixels = pixelProvider.DetachPixelData();
The DetachPixelData function returns a byte array of pixel data synchronously. This example requests pixel data in the Rgba8 pixel format, so each element in the array corresponds to a single color channel value.
Step 4: Loop through the pixels
Now that you have the pixel data, loop through and process it. The code here zeroes out the green and blue channels, leaving the red and alpha channels.
var width = decoder.OrientedPixelWidth;
var height = decoder.OrientedPixelHeight;
for (var i = 0; i < height; i++)
{
for (var j = 0; j < width; j++)
{
pixels[(i * height + j) * 4 + 1] = 0; // Green channel (RGBA)
pixels[(i * height + j) * 4 + 2] = 0; // Blue channel (RGBA)
}
}
}
Note In Step 2, the call to GetPixelDataAsync specified that the decoder return the pixel data with EXIF orientation applied. So it is important to use the OrientedPixelWidth and OrientedPixelHeight properties, instead of PixelWidth and PixelHeight when you want to get the image dimensions. The OrientedPixelWidth and OrientedPixelHeight properties reflect any change in dimensions resulting from EXIF orientation.