我正在尝试将相机元数据复制到Bitmap中,并且因为元数据中的每个值都是16位(或ushort),我认为将它显示在16bpp的Garyscale Bitmap中是明智的。我写的代码如下:
// Getting the metadata from the device
metaData = new DepthMetaData();
dataSource.GetMetaData(metaData);
// Setting up bitmap, rect and data to use pointer
Bitmap bitmap = new Bitmap(metaData.XRes, metaData.YRes, PixelFormat.Format16bppGrayScale);
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData data = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format16bppGrayScale);
// Pointer pointing to metadata
ushort* ptrMetaData = (ushort*)dataSource.DepthMapPtr.ToPointer();
lock(this)
{
// Runs through the whole bitmap and assigns the entry in the metadata
// to a pixel
for (int y = 0; y < bitmap.Height; ++y)
{
ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;
for (int x = 0; x < bitmap.Width; ++x, ++ptrMetaData)
{
ptrDestination[x] = (ushort)*ptrMetaData;
}
}
}
// Once done unlock the bitmap so that it can be read again
bitmap.UnlockBits(data);
运行元数据的XRes = 640且YRes = 480时。代码在“ptrDestination [x] =(ushort)* ptrMetaData;”的for循环中抛出内存访问异常。仅运行240,总数的一半,行。
我使用8bpp,我降低了分辨率并且效果很好,所以我不明白为什么它不应该在这里。也许有人发现了问题。
非常感谢
答案 0 :(得分:2)
ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;
data.Stride值以字节表示,而不是ushorts。因此指针偏离了2倍,因此它在bitmap.Height / 2处爆炸。你的for循环被破坏,交换bitmap.Width和bitmap.Height。 lock关键字在这里没有多大意义,您正在访问除dataSource之外的线程本地数据。修正:
for (int y = 0; y < bitmap.Height; ++y)
{
ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride / 2;
for (int x = 0; x < bitmap.Width; ++x, ++ptrMetaData)
{
ptrDestination[x] = (ushort)*ptrMetaData;
}
}