由于 Marshal 类在 WinRT 上不可用 - 最高效的方法是使用SafeMemoryMappedViewHandle (SafeBuffer)。
此方法还可以处理具有多字节组件的像素格式,而无需使用 BinaryReader 并逐个组件读取它(RGBA16,每个组件 16 位)。使用解码器的BitmapPixelFormat属性找出像素格式,并使用适当声明的结构。
// 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;
}
注意:此方法也可以替代任何需要 Marshal.PtrToStructure 或 WinRT 上的类似等价物的操作。