用于保存16位灰度图像的结构



我需要从内存缓冲区遮罩图像(矩形区域填充黑色)。所以我天真地用ImageFormat重新使用Bitmap类。MemoryBmp API。这在我的本地机器上运行得很好:

public static void MaskBitmap(Bitmap input, Rectangle maskRegion)
{
var bytesPerPixel = Image.GetPixelFormatSize(input.PixelFormat) / 8;
var row = new byte[maskRegion.Width * bytesPerPixel];
var maskData = input.LockBits(maskRegion, ImageLockMode.WriteOnly, input.PixelFormat);
for (var i = 0; i < maskData.Height; ++i)
{
Marshal.Copy(row, 0, maskData.Scan0 + (i * maskData.Stride), row.Length);
}
input.UnlockBits(maskData);
}

然而,当部署到生产环境时,结果是下面的代码抛出了一个NotImplementedException:

var image16 = new Bitmap(512, 512, PixelFormat.Format16bppGrayScale);

我最终找到了这里:

  • https://github.com/mono/libgdiplus/blob/6.0.4/src/bitmap.c L848

所以我的问题是:c#中是否有任何现有的类,我可以重用来保存pixelformat类型的图像:

  • PixelFormat。Format8bppIndexed:
  • PixelFormat。Format16bppGrayScale:
  • PixelFormat。Format24bppRgb:

我知道GDI+不支持保存/显示16位图像,我只需要一个具有图像样式访问的内存结构。


仅供参考,我尝试了以下hack:

var image = new Bitmap(512,512,PixelFormat.Format24bppRgb);
image.Flags = ImageFlags.ColorSpaceGray;

但是Flags是只读的。

正如你所看到的,GDI+Bitmap在Linux上根本不支持16bpp灰度像素格式,实际上它在Windows上的支持也相当有限。收集了两个平台的限制后,参见不同平台上可能的像素格式的限制下的表格部分。

我需要从内存缓冲区屏蔽图像

要在Linux和Windows上使用完全托管的位图内存表示,您可以使用这个库(免责声明:由我编写)。您可以通过BitmapDataFactory.CreateBitmapData方法创建一个16bpp的灰度位图数据,该方法返回一个允许许多托管操作的IReadWriteBitmapData(请参阅列出可用扩展方法的链接)。您甚至可以通过ToBitmap扩展将其转换为实际的Bitmap,但在Linux上,这会将结果转换为具有24bpp RGB像素格式的Bitmap

的例子:

var image16 = BitmapDataFactory.CreateBitmapData(new Size(512, 512), PixelFormat.Format16bppGrayScale);
var row = image16.FirstRow;
do
{
for (int x = 0; x < image16.Width; x++)
{
// row[x] uses a Color32 structure (8 bit per color) but raw access
// enables you to use the full 16-bit color range:
row.WriteRaw<ushort>(x, 32768); // 50% gray
}
} while (row.MoveNextRow());

至于8bpp索引和24bpp RGB格式,它们在Linux上也被本地Bitmap支持,但请注意,从。net 6版本开始,System.Drawing默认只在Windows上被支持。Microsoft建议使用其他库,但是您仍然可以通过将"System.Drawing.EnableUnixSupport": true添加到runtimeconfig.json来启用Unix支持。或者,如果您决定使用我上面提到的库,只需在执行其他操作之前调用DrawingModule.Initialize(),这将启用Unix支持,而无需编辑任何配置文件。

我认为Wpf位图应该支持16位灰度。

然而,我工作过的大多数使用16位灰度图像的系统都使用自定义数据类型。比如:

public class My16BitImage{
public ushort[] Data {get;}
public int Width {get;}
public int Height {get;}
}

请注意,为了显示图像,您很可能需要将其转换为8位图像,并且您可能需要缩放值以使最大/最小值映射到最大/最小8位值。

相关内容

  • 没有找到相关文章