如何获取使用默认格式的像素数据 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

我们将向你展示如何使用 BitmapDecoder 对象从图像获取像素数据。 这些像素被打包为字节数组,且 BitmapDecoder 对象自动选择要使用的最佳格式。

BitmapDecoder 可以自动确定图像的最合适像素格式并采用该格式提供像素数据。这在加载采用支持大于 8 位/通道精度的某种格式(例如 JPEG-XR)存储的图像时非常有用。如果让 BitmapDecoder 确定最佳像素格式,则你的应用必须检测并处理像素格式和 alpha 模式的每种可能的组合,因为这些组合是在图像解码时在运行时确定的。

注意  

如果你希望获取采用特定格式的像素数据,请参阅如何获取采用特定格式的像素数据

 

你需要了解的内容

技术

先决条件

说明

步骤 1: 获取解码器对象

编写用来接收 BitmapDecoder 对象的函数的开头,并声明用来存储所检索属性的变量。

function DecodeDefaultPixels(decoder) {

使用解码器可以访问像素数据。 如果还没有解码器对象,请参阅如何解码图像

步骤 2: 获取像素数据提供程序对象

调用不带任何参数的 getPixelDataAsync 方法。返回 getPixelDataAsync 时,分配像素数据且准备使用。

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

在这种情况下,会自动确定像素格式和 Alpha 模式,并应用 EXIF 方向,而像素数据是托管到 sRGB 的颜色。有关详细信息,请参阅 getPixelDataAsync

步骤 3: 处理每种像素格式和 alpha 模式组合

因为返回的像素数据的像素格式和 alpha 模式是在运行时确定的,因此你的应用必须检测并处理每种可能的组合,很可能会使用它自己的独特代码路径。你可以通过在 BitmapDecoder 上查询 bitmapPixelFormatbitmapAlphaMode 属性,确定返回的像素数据的像素格式和 alpha 模式。

在此示例中,我们将检查每个像素的颜色通道值。因此,你必须处理不同的像素位深度和通道排序。

        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;
        }

在此示例中,我们使用 JavaScript 类型化数组以允许应用处理 16 位像素数据(由 Rgba16 像素格式返回)。detachPixelData 方法始终一个返回包含 8 位值的数组,该数组等同于使用像 C++ 那样的语言的一个原始字节缓冲区。Uint16Array 允许你访问原始像素数组中的数据,就好像它是 16 位值一样。

注意  当你创建新的类型化数组时,它会产生像素数据的另一个内存内副本。如果你要编辑一个非常大的图像,这会增加你的应用的内存消耗。

 

步骤 4: 循环操作像素

现在你有了像素数据并占有了像素的格式,请循环访问它们并对它们执行处理。此处的代码将零出绿色和蓝色通道,从而保留红色和 alpha 通道。

        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
            }
        }
    });
}

注意  如果该标志存在于图像中,则 getPixelDataAsync 的零参数超载将始终应用 EXIF 方向。 因此,当获取图像的分辨率时,使用 orientedPixelWidthorientedPixelHeight 属性(而不是 pixelWidthpixelHeight)是很重要的。 orientedPixelWidthorientedPixelHeight 属性反映从 EXIF 方向产生的分辨率上的任何更改。

 

相关主题

简单的图像处理示例

Windows.Graphics.Imaging

BitmapDecoder

GetPixelDataAsync

如何解码图像

如何获取使用特定格式的像素数据