I am trying to get the RGB value of each pixel in WinRT app. I can access an array of bytes containing PixelData
but I don\'t know how to work with that so how
Since you have a RGB image, tempBuffer[k + 0]
is the red channel, tempBuffer[k + 1]
is the green channel, and tempBuffer[k + 2]
is the blue channel, i.e. tempBuffer
is a 1D array. If you were looping over all the pixels, the pseudo code for this would be:
for i = 0 to height - 1
for j = 0 to width - 1
k = (i * width + j) * 3
r, g, b = tempBuffer[k + 0], tempBuffer[k + 1], tempBuffer[k + 2]
Since the Marshal class isn't available on WinRT - the most performant way to proceed would be to use a SafeMemoryMappedViewHandle (SafeBuffer).
This method can also handle pixelformats with multi-byte components without needing to use a BinaryReader and reading it component by component (RGBA16 with 16 bits per component). Find out what the pixel format is using the decoder's BitmapPixelFormat property and use the appropriately declared structure.
// declare more of these appropriately laid
// out structures for different pixel formats
struct RGBA16
{
public uint R;
public uint G;
public uint B;
public uint A;
}
struct RGBA8
{
public byte R;
public byte G;
public byte B;
public byte A;
}
struct BRGA8
{
public byte B;
public byte G;
public byte R;
public byte A;
}
...
var handle = GCHandle.Alloc(tempBuffer /* the raw byte[] */, GCHandleType.Pinned);
try
{
var ptr = handle.AddrOfPinnedObject();
var safeBuffer = new SafeMemoryMappedViewHandle(true /* I believe DetachPixelData returns a copy? false otherwise */)
safeBuffer.SetHandle(ptr);
#if STREAM_PROCESSING
// pixel by pixel
int offset = 0;
for (int i = 0; i < width * height; i++)
{
var pixel = safeBuffer.Read<RGBA16>(offset);
offset += RGB24bpp.Size;
}
#else
// Read it all in at once - this makes a copy
var pixels = new RGBA16[width * height];
safeBuffer.ReadArray<RGBA16>(0, pixels, 0, width * height);
#endif
}
finally
{
safeBuffer.Dispose();
handle.Free;
}
Note: This method can also be a replacement for any operation that requires Marshal.PtrToStructure or some such equivalent on WinRT.