1

我在 Windows 下创建屏幕截图并使用LockBitsGDI+ 中的函数提取像素数据,然后将其写入文件。

为了最大限度地提高性能,我还:

  • 使用与PixelFormat源位图相同,避免格式转换
  • 使用ImageLockModeUserInputBuf标志将像素数据提取到预先分配的缓冲区中
  • 这个预先分配的缓冲区(由 指向BitmapData::Scan0)是内存映射文件的一部分(以避免再次复制像素数据。)

我还将编写读取文件的代码,因此我可以使用(或发明)任何我希望的格式。但是,我更喜欢使用现有程序(理想情况下是 Web 浏览器)能够读取的众所周知的格式,因为这意味着我可以在为其他程序(读取图像的程序)编写代码之前直观地确认图像是正确的。 )

我已经成功实现了该PixelFormat32bppRGB格式,它与 32bpp BMP 文件的格式相匹配,所以如果我将像素数据直接提取到内存映射的 BMP 文件中并在其前面加上 BMP 标头,我会得到一个有效的 BMP 图像文件,它可以在 Paint 和大多数浏览器中打开。

不幸的是,我正在测试的其中一台机器以PixelFormat64bppPARGB格式返回像素(可能这受到视频适配器驱动程序的影响),并且没有相应的 BMP 像素格式。

转换为 16、24 或 32bpp BMP 格式会大大降低程序速度(并且有损),因此我正在寻找一种无需转换即可使用此像素格式的文件格式,因此我可以直接提取到内存映射文件中正如我对 32bpp 格式所做的那样。

哪些光栅图像文件格式支持 48bpp(BGR 顺序,little-endian)和/或 64bpp(BGRA 顺序,little-endian)?


编辑

到目前为止,我已经排除了这些格式:

  • BMP:深度限制为 <=32bpp(否则将是完美匹配。)
  • PNG : 样品顺序只能是 RGBA。
  • TIFF : 样品顺序只能是 RGBA。

可能的部分解决方案:

  • OpenEXR:仅 48bpp。采样顺序按通道名称的字母顺序排列;BGR 适合,但 BGRA 不适合。
4

6 回答 6

3

似乎您需要标准格式的唯一原因是出于显示/测试目的。因此,滚动您自己的格式,但转换为 PNG 或 TIFF 进行显示。然后继续前进……生命短暂。

于 2010-04-05T03:01:50.353 回答
2

您真的想为 14 种不同的 PixelFormat 中的每一种实现并仔细测试单独的阅读器吗?我知道到目前为止你只遇到过其中的 2 个,但我保证那里有几乎所有其他 12 个的视频卡。作为一个简单的例子,将你的显示器设置为 256 色......

你说你想最大化性能,但是将位图写入磁盘上的文件,即使使用内存映射,平均需要的时间比将它转换为与设备无关的位图所需的时间更多记忆。另外,如果将 64 位位图转换为 32 位位图,则生成的文件将花费一半的时间来写入,因此它实际上可能更快。

于 2010-03-26T16:36:28.320 回答
1

支持哪些位图颜色深度取决于您的 Windows 版本,这意味着 gdi+ 版本,而不是图形适配器。

您也可以使用 TIFF 或 PNG(png 有很多参数,我认为您也可以告诉它进行未压缩)。您也可以考虑 RAW 格式。

具有 .net 包装器的图像库 imagemagick 包括支持数百种图像格式,无论您最后决定起诉哪种格式,我相信它都支持它:)

于 2010-03-26T16:23:47.423 回答
1

当桌面和 Web 文件格式让您失望时,请考虑使用大炮:FITS(灵活的图像传输系统)或HDF5,甚至可能是DICOM

于 2010-04-05T08:14:52.173 回答
0

PNG?48 位 + 阿尔法 = 64 位

对于压缩,“可以仅使用未压缩的 deflate 块来存储未压缩的数据”

于 2010-03-26T16:22:53.260 回答
0

文件的读取与写入的性能一样重要吗?如果您可以轻松填充缓冲区,然后在方便时阅读,这应该是小菜一碟。只需有一个 1 字节的标头代表数据格式,然后是您获得的原始数据。

于 2010-03-30T12:41:51.337 回答