如何在 C# 中使用指针正确寻址 16bpp

发布于 2025-01-08 09:49:37 字数 1316 浏览 3 评论 0原文

我正在尝试将相机元数据复制到位图中,并且由于元数据中的每个值都是 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 一起使用,降低了分辨率,效果很好,所以我不明白为什么不应该在这里使用。也许有人发现了问题。

已经谢谢了

I am trying to copy camera metadata into a Bitmap, and seing as each value in the metadata is a 16bit (or ushort) I thought it would be sensible to display it in a 16bpp garyscale Bitmap. The code I wrote is as follows:

// 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);

When running the Metadata's XRes = 640 and YRes = 480. The code throws a memory access exception in the for-loops on "ptrDestination[x] = (ushort)*ptrMetaData;" after only running though 240, half the total, lines.

I used this with 8bpp where I reduced the resolution and it worked nicely, so I don't see why it should not here. Maybe someone finds the problem.

Thanks already

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘紸啶 2025-01-15 09:49:37
    ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;

data.Stride 值以字节表示,而不是 ushort。所以指针偏离了 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;
    }
}
    ushort* ptrDestination = (ushort*)data.Scan0.ToPointer() + y * data.Stride;

The data.Stride value is expressed in bytes, not ushorts. So the pointer is off by a factor of 2 so it bombs at bitmap.Height/2. Your for loops are broken, swap bitmap.Width and bitmap.Height. The lock keyword doesn't make much sense here, you are accessing thread-local data, other than dataSource. Fix:

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文