在 C# 位图中锁定矩形时锁定指针

发布于 2024-07-26 21:23:11 字数 1273 浏览 12 评论 0原文

这可能是重复以下未回答的问题:

 Help with bitmap lock - Format8bppIndexed

我按以下方式锁定图像:

// PixelFormat is 8BppIndexed in my case.
Bitmap bmp = new Bitmap("mySampleImage.tif");

// ClipRectangle will be a Rectangle such as {x=128, y=290, width=250, height=200},
// selected by the user by seeing the image on screen. Thus, it's a valid region
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);

unsafe
{
  byte* origin = (byte*)data.Scan0.ToPointer();

  // Processing...
}

在处理部分中,我在 Y 方向上逐步遍历 ClipRectangle 中的像素。 但是,应该有效的像素返回内存访问错误,表示我无法取消引用指针。

例如,在 704x600 图像中使用:

ClipRectangle = {x=128, y=290, width=250, height=200}

像素 (128x321) 应该有效。 通过手动输入数学公式来获取中间窗口中的像素,我得到以下结果:

origin + (321 * stride) + 128
0x053a80c0
    *(origin + (321 * stride) + 128): Cannot dereference 'origin + (321 * stride) + 128'. The pointer is not valid.

步幅为 704,我的软件中的逻辑得出了与中间窗口完全相同的指针位置,因此一切看起来都是正确的。 290-320 之间的 Y 像素可以很好地取消引用。 如果我锁定整个位图,我的所有逻辑都会正常进行,但我怀疑我是否获得了正确的像素,或者锁定矩形在 LockBits 中的使用方式。

当我仅锁定所需区域时,为什么无法访问 BitmapData 中预期锁定的像素?

This may be a repeat of the following unanswered question:

 Help with bitmap lock - Format8bppIndexed

I'm locking an image in the following manner:

// PixelFormat is 8BppIndexed in my case.
Bitmap bmp = new Bitmap("mySampleImage.tif");

// ClipRectangle will be a Rectangle such as {x=128, y=290, width=250, height=200},
// selected by the user by seeing the image on screen. Thus, it's a valid region
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);

unsafe
{
  byte* origin = (byte*)data.Scan0.ToPointer();

  // Processing...
}

In the processing section, I step through the pixels in the ClipRectangle in the Y direction. However, a pixel that should be valid returns with a memory access error, saying I cannot dereference the pointer.

For example, in a 704x600 image using:

ClipRectangle = {x=128, y=290, width=250, height=200}

The pixel (128x321) should be valid. By manually typing in the math to get that pixel in the intermediate window, I get the following:

origin + (321 * stride) + 128
0x053a80c0
    *(origin + (321 * stride) + 128): Cannot dereference 'origin + (321 * stride) + 128'. The pointer is not valid.

Stride is 704, the logic in my software comes up with the exact pointer location as the intermediate window, so everything seems right. The Y pixels from 290-320 can be dereferenced just fine. If I instead lock the entire Bitmap, all my logic proceeds fine, but I have doubts about whether I'm getting the right pixels, or how the locking rectangle is used in LockBits.

Why can I not access the expected locked pixels in the BitmapData when I lock only the region I need?

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

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

发布评论

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

评论(1

探春 2024-08-02 21:23:12

当您使用带有偏移量的矩形锁定位时,BitmapData.Scan0 不会返回位图 原点,而是返回指定的矩形原点。

因此,如果您使用:

Rectangle rect = new Rectangle(128, 290, 250, 200);
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);

则距 Scan0 的最大偏移量为 (250 * Stride) + 200

换句话说,(128x321) 处的像素将位于 (Scan0 + (321 - 290) * Stride) 处。

When you lock bits using a rectangle with an offset, BitmapData.Scan0 doesn't return the bitmap origin, but rather the specified rectangle origin.

So, if you used:

Rectangle rect = new Rectangle(128, 290, 250, 200);
BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);

then the maximum offset from Scan0 is (250 * Stride) + 200.

In other words, the pixel at (128x321) would be at (Scan0 + (321 - 290) * Stride).

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