如何从 WIC 解码器确定自上而下/自下而上?

Posted

技术标签:

【中文标题】如何从 WIC 解码器确定自上而下/自下而上?【英文标题】:How to determine top-down/bottom-up from WIC decoder? 【发布时间】:2020-10-13 21:54:28 【问题描述】:

我正在使用 WIC (Windows Imaging Component) 来解码图像文件并访问像素数据。我正在尝试找出像素顺序(即自下而上或自上而下)。

我使用IWICImagingFactory::CreateDecoderFromFileName 创建解码器,从中获取(第一)帧(IWICBitmapFrameDecode)。对于帧,我使用GetPixelFormatGetSize 计算缓冲区大小,最后我使用CopyPixels 将解码后的像素数据放入我的缓冲区。

这适用于各种 JPEG 文件,以自上而下的顺序为我提供像素行,并且像素按 BGRX 顺序排列 (GUID_WICPixelFormat32bppBGR)。

但是,当我尝试使用 GIF 文件时,像素行以自下而上的顺序出现。报告的像素格式为 RGBA (GUID_WICPixelFormat32bppRGBA),但基本事实显示通道顺序为 BGRA(每个 32 位像素的低字节为蓝色,就像 JPEG)。

我的主要问题:有没有办法查询像素数据的自上而下/自下而上的方向?

我发现了一个类似的问题,询问使用 JPEG 源时的旋转,答案是查询 EXIF 数据以了解图像是否旋转。但 EXIF 不与 GIF 一起使用。 所以我想知道我是否应该假设像素总是自下而上,除了那些确实有一个 EXIF 方向的像素。 2020 年 6 月 25 日更新 不,JPEG 方向是中性的,GIF 没有方向信息,但 MS Paint 和其他程序可以以正确的方向打开文件。

我的第二个问题:GIF 解码器的通道顺序 (RGB/BGR) 不正确是怎么回事?

不仅如此,WIC 文档还说将GIF decoder should return indexes 转换为颜色表 (GUID_WICPixelFormat8bppIndexed) 而不是实际的像素值。是否有可能我的机器上的某些软件安装了自己的有缺陷的 GIF 解码器,取代了 Windows 10 附带的那个?

【问题讨论】:

你应该问两个不同的问题。第一个,你在找这个吗:***.com/a/60112084/403671 @Simon Mourier:我在这里提出第二个问题只是因为 (1) 它可能与主要问题有关,以及 (2) 包含有关我尝试过的所有相关信息,并且学到为止。将这些信息放在一个单独的问题中似乎会降低对第一个问题做出体面回应的机会。这不是我的第一个 SO 牛仔竞技表演。 【参考方案1】:

要查询支持它的格式的照片方向,您应该使用System.Photo.Orientation 使用IWICMetadataQueryReader 接口的照片元数据策略(或文件格式特定元数据查询路径之一)。

至于GetPixelFormat() 报告“不正确”的像素格式,就在备注部分:

此方法返回的像素格式不一定是图像存储的像素格式。编解码器可以执行从存储像素格式到输出像素格式的格式转换。

Windows 下图像位图的本机字节顺序是 BGRA,这就是您从解码器得到的。如果您想要其他格式的图像,您需要使用IWICImagingFactory::CreateFormatConverter()创建格式转换器并在复制之前转换图像数据。

最后,GIF 没有方向元数据,因为它总是从上到下编码。您获得垂直反转图像的最可能原因是因为您直接从解码器读取它 - 请尝试在转换器上调用 CopyPixels()

【讨论】:

System.Photo.Orientation 是指向正确方向的一个很好的指针,非常感谢。关于GetPixelFormat,我知道它可能与存储顺序不同,但是对于某些图像,它与解码器输出的不匹配。我 am 使用 CopyPixels(正如我在问题中指出的那样),但有些图像是倒置的,而另一些则不是。还是挺令人费解的。 您正在使用 CopyPixels,但您是在转换器上还是在框架上使用它? 我在框架上调用 CopyPixels。我根本没有使用转换器。我的代码可以处理任何像素格式和方向,只要它知道它是什么。但是我得到的与 GetPixelFormat (在框架上)所说的我应该得到的不匹配。此外,在 GIF 的情况下,报告的像素格式不是文档声称的格式,也不是我实际收到的像素格式。 这正是建议使用转换器的原因——因此您可以确保无论解码器的具体情况如何,您将始终获得所需的相同输出格式。

以上是关于如何从 WIC 解码器确定自上而下/自下而上?的主要内容,如果未能解决你的问题,请参考以下文章

网络协议

句型的短语,直接短语,句柄

如何从 Web 获取 base64 并在 Swift 中解码?

自上而下与自下而上的递归数据定义?

确定正确的解码技术

如何使用转义的 unicode 解码字符串?