Freigeben über


Acceder a los pixeles de una imagen en Apps de WinRT

Intermedio

Otros artículos de manipulación de imágenes en WinRT

Cuando se realiza manipulación avanzada de imágenes es necesario acceder a la información de ellas a nivel de píxeles, más exactamente a nivel de bytes.

Para lograrlo debemos hace uso de la clase BitMapDecoder pero te puede dar algunos, o muchos problemas si recién te inicias con el framework de WinRT.

Crear una instancia de BitMapDecoder

No es posible crear una nueva instancia de BitMapDecoder puesto que su no tiene constructores publicos; la forma indicad para crear un nuevo objeto de esta clase es usando el método estático BitMapDecoder.CreateAsync. Así que ya esta la pimera parte solucionada.

 var decoder = await BitmapDecoder.CreateAsync(IRandomAccessStream);  

IRandomAccessStream

Para inicializar el BitMapDecoder se requiere un IRandomAccessStream puede sonar asustadizo, no es más que un stream al archivo que contiene la imagen, desde un StorageFolder usas el método OpenReadAsync el cual te devuelve un tipo compatible.

 var localFolder = Package.Current.InstalledLocation;  
var folder = await localFolder.GetFolderAsync("Assets");  
var imgfile = await folder.GetFileAsync("conejo.bmp");  
var filestream = await imgfile.OpenReadAsync();  
var decoder = await BitmapDecoder.CreateAsync(filestream);  

Ahora ya tenemos listo el decoder!

Obteniendo los pixeles

Teniendo ya el decoder listo no es más sino extraer los pixeles, en el decoder el método GetPixelDataAsync devuelve un PixelDataProvider, este a su ves con el método DetachPixelData devuelve el arreglo de bytes con la información de color.

 var pxDataProvider = await decoder.GetPixelDataAsync();
byte[] pxData = pxDataProvider.DetachPixelData();

Este arreglo de bytes es una secuencia de pixeles de 4 bytes, es decir por cada punto de color de la imagen tenemos 4 bytes que representan respectivamente los componentes de color BGRA (blue, green, red, alpha), por fortuna para todos esta información de color esta en RAW (cruda) por lo que no encontraremos temas mas complicados como bytes de relleno ni nada de esas cosas, por ende cada cuatro byte es un color y nada más.

Sobre estos bytes de color podemos hacer las modificaciones que se requieran sobre la imagen.

Este es el código completo

 var localFolder = Package.Current.InstalledLocation;  
var folder = await localFolder.GetFolderAsync("Assets");  
var imgfile = await folder.GetFileAsync("conejo.bmp");

var filestream = await imgfile.OpenReadAsync();  
var decoder = await BitmapDecoder.CreateAsync(filestream);  
var pxDataProvider = await decoder.GetPixelDataAsync();  
byte[] pxData = pxDataProvider.DetachPixelData();  

Como volver esta información de bytes a una imagen? esto es tema de los dos proximos post :)