如何取得預設格式的像素資料 (HTML)
[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]
以下將說明如何使用 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 方向而產生的任何維度變更。