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

Posted

技术标签:

【中文标题】在 .NET Format16bppGrayScale 图像中设置单个像素【英文标题】:Set individual pixels in .NET Format16bppGrayScale image 【发布时间】:2011-03-29 07:33:41 【问题描述】:

我正在尝试使用 .NET 在内存中渲染一个需要 16 位灰度的小位图。位图的格式设置为 PixelFormat.Format16bppGrayScale。但是,Bitmap.SetPixel 采用 Color 参数。对于 R、B 和 G(以及可选的 A),颜色依次占用一个字节。

在绘制位图时如何指定 16 位灰度值而不是 8 位值?

【问题讨论】:

【参考方案1】:

无论图像格式如何,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

【讨论】:

谢谢。我最初使用 SetPixel 是因为我只是将 512x512 位图写入文件系统(创建通过围绕垂直轴旋转高斯分布创建的实体的高度图,以便在另一个程序中使用)。 SetPixel 对于大多数应用程序来说太慢了。由于您引用的限制,我最终选择了另一种高度图格式,但您的答案是正确且完整的,因此可以接受。

以上是关于在 .NET Format16bppGrayScale 图像中设置单个像素的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 中使用自定义格式对 TimeSpan 对象进行 String.Format ?

JavaScript:使用 .NET String.Format() 之类的文化格式化数字/货币?

.NET Assembly File Format

TIME_FORMAT(time, format)

Python format语法

在 .NET 6 中使用 dotnet format 格式化代码