如何获取使用默认格式的像素数据 (HTML)
[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]
我们将向你展示如何使用 BitmapDecoder 对象从图像获取像素数据。 这些像素被打包为字节数组,且 BitmapDecoder 对象自动选择要使用的最佳格式。
BitmapDecoder 可以自动确定图像的最合适像素格式并采用该格式提供像素数据。这在加载采用支持大于 8 位/通道精度的某种格式(例如 JPEG-XR)存储的图像时非常有用。如果让 BitmapDecoder 确定最佳像素格式,则你的应用必须检测并处理像素格式和 alpha 模式的每种可能的组合,因为这些组合是在图像解码时在运行时确定的。
注意
如果你希望获取采用特定格式的像素数据,请参阅如何获取采用特定格式的像素数据。
你需要了解的内容
技术
先决条件
- 我们假设你能够创建使用 JavaScript 的基本 Windows 运行时应用。有关详细信息,请参阅构建你的第一个使用 JavaScript 的 Windows 运行时应用。
- 你已具有一个 BitmapDecoder 对象。 如何解码图像指导你创建该对象。
说明
步骤 1: 获取解码器对象
编写用来接收 BitmapDecoder 对象的函数的开头,并声明用来存储所检索属性的变量。
function DecodeDefaultPixels(decoder) {
使用解码器可以访问像素数据。 如果还没有解码器对象,请参阅如何解码图像。
步骤 2: 获取像素数据提供程序对象
调用不带任何参数的 getPixelDataAsync 方法。返回 getPixelDataAsync 时,分配像素数据且准备使用。
decoder.getPixelDataAsync().then(function (pixelDataProvider) {
在这种情况下,会自动确定像素格式和 Alpha 模式,并应用 EXIF 方向,而像素数据是托管到 sRGB 的颜色。有关详细信息,请参阅 getPixelDataAsync。
步骤 3: 处理每种像素格式和 alpha 模式组合
因为返回的像素数据的像素格式和 alpha 模式是在运行时确定的,因此你的应用必须检测并处理每种可能的组合,很可能会使用它自己的独特代码路径。你可以通过在 BitmapDecoder 上查询 bitmapPixelFormat 和 bitmapAlphaMode 属性,确定返回的像素数据的像素格式和 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 方向。 因此,当获取图像的分辨率时,使用 orientedPixelWidth 和 orientedPixelHeight 属性(而不是 pixelWidth 和 pixelHeight)是很重要的。 orientedPixelWidth 和 orientedPixelHeight 属性反映从 EXIF 方向产生的分辨率上的任何更改。