【问题标题】:How to properly address 16bpp with pointers in C#如何在 C# 中使用指针正确寻址 16bpp
【发布时间】:2012-02-24 13:00:01
【问题描述】:

我正在尝试将相机元数据复制到位图中,并且由于元数据中的每个值都是 16 位(或 ushort),我认为将其显示在 16bpp garyscale 位图中是明智的。我写的代码如下:

// 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 一起使用,我降低了分辨率并且效果很好,所以我不明白为什么它不应该在这里。也许有人发现了问题。

已经谢谢了

【问题讨论】:

  • 注意:对于 8bpp,我使用 byte 而不是 ushort 并在分配给像素之前将元数据右移了 8 次

标签: c# pointers bitmap 16-bit


【解决方案1】:
    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;
    }
}

【讨论】:

  • Hieght 和 Width 被交换了,因为我显然无法将内容复制到 Notepad++ 中,但 Stride 是明确的解决方案!非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2019-11-22
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 1970-01-01
  • 2012-02-20
相关资源
最近更新 更多