How to get pixel data in the default format (HTML)

[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 the BitmapDecoder object automatically selects the best format to use.

BitmapDecoder can automatically determine the best fit pixel format for the image and provide pixel data in that format. This can be useful if you are loading images stored in a format, such as JPEG-XR, that supports greater than 8 bit-per-channel precision. If you have BitmapDecoder determine the optimal pixel format, you must detect and handle every possible combination of pixel format and alpha mode, as these are determined at runtime when the image is decoded.

Note  

If you want to get the pixel data in a particular format, see How to get pixel data in a particular format.

 

What you need to know

Technologies

Prerequisites

Instructions

Step 1: Get a decoder object

Write the beginning a function that receives a BitmapDecoder object and declare variables to store the retrieved properties in.

function DecodeDefaultPixels(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 with no parameters. When getPixelDataAsync returns, the pixel data is allocated and ready to use.

decoder.getPixelDataAsync().then(function (pixelDataProvider) {

In this case, the pixel format and alpha mode are automatically determined, EXIF orientation is applied and the pixel data is color managed to sRGB. See getPixelDataAsync for more info.

Step 3: Handle each pixel format and alpha mode combination

Because the pixel format and alpha mode of the returned pixel data is determined at runtime, your app must detect and handle each potential combination, with its own unique code path. You can determine the pixel format and alpha mode of the returned pixel data by querying the bitmapPixelFormat and bitmapAlphaMode properties on the BitmapDecoder.

In this example, we walk each pixel’s color channel values. So, you must handle different pixel bit depths and channel orderings.

        var rawPixels = pixelDataProvider.detachPixelData();
        var pixels, bOffset, gOffset; // Assign these in the below switch block.

        switch (decoder.bitmapPixelFormat) {
            case Windows.Graphics.Imaging.BitmapPixelFormat.rgba16:
                // Allocate a typed array with the raw pixel data
                var pixelBufferView_U8 = new Uint8Array(rawPixels);

                // Uint16Array provides a typed view into the raw 8 bit pixel data.
                pixels = new Uint16Array(pixelBufferView_U8.buffer);
                gOffset = 1;
                bOffset = 2;
                break;

            case Windows.Graphics.Imaging.BitmapPixelFormat.rgba8:
                // For 8 bit pixel formats, just use the returned pixel array.
                pixels = rawPixels;
                gOffset = 1;
                bOffset = 2;
                break;

            case Windows.Graphics.Imaging.BitmapPixelFormat.bgra8:
                // For 8 bit pixel formats, just use the returned pixel array.
                pixels = rawPixels;

                // Bgra8 uses a different channel ordering than Rgba8 and Rgba16.
                gOffset = 1;
                bOffset = 0;
                break;
        }

        switch (decoder.bitmapAlphaMode) {
            // For our processing algorithm, ignore alpha mode.
            case Windows.Graphics.Imaging.BitmapAlphaMode.premultiplied:
            case Windows.Graphics.Imaging.BitmapAlphaMode.ignore:
            case Windows.Graphics.Imaging.BitmapAlphaMode.straight:
                break;
        }

In this example, we use JavaScript typed arrays to allow the app to handle 16 bit pixel data (returned by the Rgba16 pixel format). The detachPixelData method always returns an array containing 8 bit values, which is is equivalent to a raw byte buffer in a language like C++. A Uint16Array allows you to access the data in the raw pixel array as if it were 16 bit values.

Note  When you create a new typed array, it results in another in-memory copy of the pixel data. If you are editing a very large image, this increases the memory consumption of your app.

 

Step 4: Loop through the pixels

Now that you have the pixel data and have accounted for the format of the pixels, loop through and perform processing on them. The code here zeroes out the green and blue channels, leaving the red and alpha channels.

        var orientedHeight = decoder.orientedPixelHeight;
        var orientedWidth = decoder.orientedPixelWidth;

        for (var i = 0; i < orientedHeight; i++) {
            for (var j = 0; j < orientedWidth; j++) {
                pixels[(i * orientedHeight + j) * 4 + gOffset] = 0; // Green channel
                pixels[(i * orientedHeight + j) * 4 + bOffset] = 0; // Blue channel
            }
        }
    });
}

Note  The zero parameter overload of getPixelDataAsync always applies EXIF orientation if the flag is present in the image. So, when getting the dimensions of the image it is important to use the orientedPixelWidth and orientedPixelHeight properties, instead of pixelWidth and pixelHeight. The orientedPixelWidth and orientedPixelHeight properties reflect any change in dimensions resulting from EXIF orientation.

 

Simple Imaging sample

Windows.Graphics.Imaging

BitmapDecoder

GetPixelDataAsync

How to decode an image

How to get pixel data in a particular format