【问题标题】:WIC HEIF HEIC image decoding C++WIC HEIF HEIC 图像解码 C++
【发布时间】:2021-01-25 10:00:21
【问题描述】:

Windows Imaging Component 用于解码 heif 图像。但是,成功解码图像需要来自 microsoft 商店的额外应用程序(heif 图像扩展、hevc 视频扩展)。

没有它们,WIC api 将返回空白图像。现在我希望能够以编程方式确定 heif 文件是否可以正确解码。

我尝试使用DXVA Checker 来定位所需解码器类型的存在,它应该是WIC_HEIF_Decoder。但我找不到它在任何地方注册。

有一个 GUID 键,但是 CLSID_WICHeifDecoder 记录了here,我认为即使缺少解码器也可以在系统中注册它。

有人知道怎么做吗?

【问题讨论】:

  • 什么是“WIC_HEIF_Decoder”? Microsoft 提供的 HEIF/HEIC guid 是 CLSID_WICHeifDecoder。如果它已注册,则 WIC 可以解码 HEIF/HEIC 图像(但实际上,并非所有 Windows 都安装了它,在这种情况下,它不会被注册)。你到底想做什么?
  • 这正是问题之一。在机器上定义了 CLSID_WICHeifDecoder,但缺少实际实现
  • “定义”是什么意思?
  • 微软通过添加 HEIC GUID 而不实际安装 h265 图像解码器,在最近的 Windows 10 更新中引入了 HEIC 编解码器混乱。 HEIC 解码器只是关于文件结构,而不是实际的图像解码。用户必须支付 1 美元才能从 Windows Store 下载实际的 h265 编解码器。最简单的解决方案是安装免费的 CopyTrans HEIC WIC 解码器copytrans.net/copytransheic。在页面上不清楚这是 WIC 编解码器,但实际上就是这样。它包含 HEIC 文件格式 + h265 解码器。

标签: c++ winapi ms-media-foundation heif heic


【解决方案1】:

如果您计划使用 WIC 解码器,您应该使用 WIC API 而不是 Media Foundation API 来检查可用性,即使两个解码器都已知 - 目前 - 打包在一起并且属于同一个 Windows 应用商店应用程序(扩展名)。

您应该能够使用 IWICImagingFactory::CreateComponentEnumerator 枚举解码器并确定 HEIF 是否在可用的解码器中。

微软 HEIF 解码器

  • 类标识符:CLSID_WICHeifDecoder
  • 签名状态:WICComponentSigned
  • 作者:微软
  • 供应商标识符:{F0E749CA-EDEF-4589-A73A-EE0E626A2A2B}
  • 版本:1.0.0.0
  • 规范版本:1.0.0.0
  • 友好名称:Microsoft HEIF 解码器
  • IWICBitmapCodecInfo:
    • 容器格式:GUID_ContainerFormatHeif
    • 像素格式:GUID_WICPixelFormat32bppBGR
    • 色彩管理版本:1.0.0.0
    • MIME 类型:image/heic,image/heif,image/avci,image/heic-sequence,image/heif-sequence,image/avcs,image/avif,image/avif-sequence
    • 文件扩展名:.heic,.heif,.avci,.heics,.heifs,.avcs,.avif,.avifs
    • 模式:576

您可能更喜欢将IWICImagingFactory::CreateDecoderGUID_ContainerFormatHeif 一起使用,因为您应该对解码能力而不是对特定解码器实现更感兴趣。

使用注册表查询或直接调用CoCreateInstance 来检查特定的 CLSID 很简单,但对于指定的任务没有多大意义。

【讨论】:

  • 看来今天不是写答案的好日子。这只是今天观察到的几个莫名其妙的反对票之一。
  • @Roman 我完全按照你说的做了。在无法查看/解码 heif 文件的机器上,我列出了解码器作者:Microsoft 名称:Microsoft HEIF 解码器扩展名:.heic、.heif、.avci、.heics、.heifs、.avcs、.avif。 aifs 版本:1.0.0.0 CLSID:{E9A4A80A-44FE-4DE4-8971-7150B10A5199}
  • 另外一种创建解码器的方法仅供参考,是从枚举的IWICComponentInfo 到 QI IWICBitmapDecoderInfo 并执行IWICBitmapDecoderInfo::CreateInstance。在 HEIF 解码器的情况下,可能存在(只是推测,我没有检查)没有 HEIF 扩展的注册信息,但即使这是真的,我也会实例创建失败。
  • CreateDecoder 也没有返回该机器的错误
  • 好的,我更新了自己。 HEIF 是一种容器格式,其结构类似于 MOV/MP4(“单帧视频”)。它可以有多种编码,所以 HEIF WIC 编解码器并不意味着你可以打开 HEIC 风格,所以你确实需要有 HEVC 解码器。所以你实际上需要同时拥有 HEIF 和 HEVC 才能打开 HEIC。 Microsoft 并未明确说明这些部分如何相互关联,但通常您的方法是正确的(我认为您需要从代码 sn-p 中删除 MFT_ENUM_FLAG_SYNCMFT - GPU 支持的解码器是异步的)。
【解决方案2】:

由于 HEIF 解码器在无法解码的 Windows 上仍然可以识别,因此这是最好的 hack imo:

为了解码 HEIF 图像,应在机器上安装 HEVC 视频扩展。 所以正确的检查是看是否有任何与HEVC输入匹配的解码类型

MFStartup(MF_VERSION);
IMFActivate** activate {};
unsigned int count {};
// Set the HEVC GUID
MFT_REGISTER_TYPE_INFO input;
input.guidMajorType = MFMediaType_Video;
input.guidSubtype = MFVideoFormat_HEVC;
// Get all available output types for HEVC input
MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER, MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_SYNCMFT, &input, nullptr, &activate, &count);
// Release interface pointers
for (size_t i = 0; i < count; i++) {
    activate[i]->Release();
}
CoTaskMemFree(activate);
MFShutdown();
return (count > 0);

【讨论】:

  • 看起来 HEIF guid 默认出现在 Windows 上,但没有 HEVC 什么都不做
猜你喜欢
  • 2018-02-21
  • 1970-01-01
  • 2022-11-07
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 2018-07-29
相关资源
最近更新 更多