在.NET Format16bppGrayScale图像中设置单个像素

11

我正在尝试使用.NET在内存中呈现一个小的位图,需要为16位灰度。该位图的格式设置为PixelFormat.Format16bppGrayScale。然而,Bitmap.SetPixel需要一个颜色参数。颜色依次需要每个R、B和G的一个字节(可选A)。

当绘制到我的位图时,如何指定16位灰度值而不是8位值?

1个回答

13

无论图像格式如何,SetPixel() 都非常慢。我实践中从不使用它。

您可以使用 LockBits 方法更快地设置像素,该方法允许您快速将托管数据封送到非托管位图字节中。

以下是示例:

Bitmap bitmap = // ...

// Lock the unmanaged bits for efficient writing.
var data = bitmap.LockBits(
    new Rectangle(0, 0, bitmap.Width, bitmap.Height),
    ImageLockMode.ReadWrite,
    bitmap.PixelFormat);

// Bulk copy pixel data from a byte array:
Marshal.Copy(byteArray, 0, data.Scan0, byteArray.Length);

// Or, for one pixel at a time:
Marshal.WriteInt16(data.Scan0, offsetInBytes, shortValue);

// When finished, unlock the unmanaged bits
bitmap.UnlockBits(data);

需要注意的是,GDI+似乎不支持16bpp灰度图像,这意味着.NET无法帮助保存16bpp灰度位图到文件或流中。请参见http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/10252c05-c4b6-49dc-b2a3-4c1396e2c3ab


1
谢谢。我最初选择了SetPixel,因为我只是将512x512位图写入文件系统(创建一个通过将高斯分布沿垂直轴旋转而创建的固体的高度图,以供另一个程序使用)。你说得对,SetPixel对于大多数应用程序来说太慢了。由于你提到的限制,我最终选择了另一种高度图格式,但你的答案是正确和完整的,所以我接受了它。 - Eric J.
var pixels = (ushort*)data.Scan0; 然后 pixels[i] = myUInt16; - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接