繁体   English   中英

保存 16 位灰度图像的结构

[英]Structure for holding a 16bits grayscale image

我需要屏蔽来自 memory 缓冲区的图像(用黑色填充的矩形区域)。 因此,我天真地将Bitmap class 与ImageFormat.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);

我最终追踪到了这里:

所以我的问题是:c# 中是否有任何现有的 class 我可以重新使用来保存像素格式类型的图像:

  • PixelFormat.Format8bppIndexed:
  • PixelFormat.Format16bppGrayScale:
  • PixelFormat.Format24bppRgb:

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


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

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

但是Flags是只读的。

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

但是,我处理过的大多数使用 16 位灰度图像的系统都使用自定义数据类型。 就像是:

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

请注意,为了显示图像,您很可能无论如何都需要将其转换为 8 位图像,并且您可能需要缩放值以使最大/最小值 map 成为最大/最小 8 位值。

如您所见,GDI+ Bitmap在 Linux 上根本不支持 16bpp 灰度像素格式,实际上它在 Windows 上的支持也非常有限。 在我收集了两个平台的限制后,请参阅此处“不同平台上可能的像素格式的限制”部分下的表格。

我需要屏蔽来自 memory 个缓冲区的图像

要在 Linux 和 Windows 上使用 bitmap 的完全托管内存表示,您可以使用库(免责声明:由我编写)。 您可以通过BitmapDataFactory.CreateBitmapData方法创建一个 16bpp 灰度 bitmap 数据,该方法返回一个允许大量托管操作的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 indexed 和 24bpp RGB 格式,原生Bitmap也支持 Linux,但请注意,从版本 .NET 开始,6 System.Drawing 默认仅支持 Windows Microsoft 建议改用其他库,但您仍然可以通过将"System.Drawing.EnableUnixSupport": true添加到runtimeconfig.json来启用 Unix 支持。 或者,如果您决定使用我上面提到的我的库,只需先调用DrawingModule.Initialize() 即可启用Unix 支持,而无需编辑任何配置文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM