Como obter dados de pixel no formato padrão (HTML)
[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente ]
Mostramos como usar um objeto BitmapDecoder para obter dados de pixel de uma imagem. Os pixels são empacotados como uma matriz de bytes e o objeto BitmapDecoder escolhe automaticamente o melhor formato a ser usado.
O BitmapDecoder pode determinar automaticamente o melhor formato de pixel para a imagem e fornecer dados de pixel nesse formato. Isso pode ser útil se você está carregando imagens armazenadas em um formato, como JPEG-XR, que dá suporte a uma precisão superior a 8 bits por canal. Se você fizer com que o BitmapDecoder determine o formato de pixel ideal, detecte e manipule cada combinação possível de formato de pixel e modo alfa, porque estes são determinados em tempo de execução quando a imagem é decodificada.
Observação
Se quiser obter os dados de pixel em um determinado formato, veja Como obter dados de pixel em um determinado formato.
O que você precisa saber
Tecnologias
- Compilando seu primeiro aplicativo do Tempo de Execução do Windows em JavaScript
- Windows.Graphics.Imaging
Pré-requisitos
- Presumimos que você consiga criar um aplicativo básico do Tempo de Execução do Windows em JavaScript. Para obter mais informações, veja Compilando seu primeiro aplicativo do Tempo de Execução do Windows em JavaScript.
- Você tem um objeto BitmapDecoder. O tópico Como decodificar uma imagem percorre com você o processo.
Instruções
Etapa 1: Obter um objeto de decodificador
Grave no início uma função que recebe um objeto BitmapDecoder e declare as variáveis para armazenar as propriedades recuperadas.
function DecodeDefaultPixels(decoder) {
O decodificador permite acessar os dados de pixel. Se você ainda não tem um objeto de decodificador, veja Como decodificar uma imagem.
Etapa 2: Obter o objeto do provedor de dados em pixel
Chame o método getPixelDataAsync sem parâmetros. Quando getPixelDataAsync é retornado, os dados de pixel são alocados e estão prontos para uso.
decoder.getPixelDataAsync().then(function (pixelDataProvider) {
Nesse caso, o formato dos pixels e o modo alfa são determinados automaticamente, a orientação EXIF é aplicada e os dados dos pixels são gerenciados por cores para sRGB. Veja getPixelDataAsync para saber mais.
Etapa 3: Manipular cada combinação de formato de pixel e modo alfa
Como o formato de pixel e o modo alfa dos dados de pixel retornados são determinados em tempo de execução, seu aplicativo precisa detectar e manipular cada combinação em potencial, com seu próprio caminho de código exclusivo. Você pode determinar o formato de pixel e o modo alfa dos dados de pixel retornados consultando as propriedades bitmapPixelFormat e bitmapAlphaMode no BitmapDecoder.
Nesse exemplo, percorremos os valores de canal de cor de cada pixel. Assim, você precisa manipular diferentes profundidades de bits de pixels e ordens de canal.
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;
}
Nesse exemplo, usamos matriz tipada JavaScript para permitir que o aplicativo manipule dados de pixel de 16 bits (retornados pelo formato de pixel Rgba16). O método detachPixelData sempre retorna uma matriz que contém valores de 8 bits, que é equivalente a um buffer de bytes bruto em uma linguagem como C++. Um Uint16Array permite acessar os dados na matriz de pixels bruta como se fossem valores de 16 bits.
Observação Quando você cria uma nova matriz tipada, ela resulta em outra cópia em memória dos dados de pixel. Se você estiver editando uma imagem muito maior, isso aumentará o consumo de memória do aplicativo.
Etapa 4: Executar um loop nos pixels
Agora que você tem os dados de pixel e justificou o formato dos pixels, execute um ciclo e o processamento deles. O código aqui torna zero os canais verde e azul, deixando os canais vermelho e alfa.
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
}
}
});
}
Observação A sobrecarga do parâmetro zero de getPixelDataAsync sempre aplica orientação EXIF se o sinalizador está presente na imagem. Assim, ao obter as dimensões da imagem, é importante usar as propriedades orientedPixelWidth e orientedPixelHeight, em vez de pixelWidth e pixelHeight. As propriedades orientedPixelWidth e orientedPixelHeight refletem qualquer mudança nas dimensões resultantes da orientação EXIF.