实现 IWICBitmapSourceTransform

IWICBitmapSourceTransform

虽然是可选的,但我们强烈建议每个解码器在帧级解码类上实现此接口,因为它可以提供重大的性能优势。 当应用程序请求感兴趣的特定区域、大小、方向或像素格式时,Windows 图像处理组件 (WIC) 针对 IWICBitmapFrameDecode 对象上的此接口调用 IUnknown::QueryInterface,而不是仅以全分辨率解码整个图像,然后应用请求的转换。 如果帧解码器支持它,WIC 会调用相应的方法,以确定帧解码器是否可以执行请求的转换,或者确定解码器可以提供给请求的解码器的最接近的大小或像素格式。 如果解码器可以执行请求的转换或转换,WIC 会使用适当的参数调用 CopyPixels 。 如果解码器可以执行某些操作, 但并非所有请求的转换,WIC 会要求解码器执行它可以执行的转换,并使用 WIC 转换对象 (IWICBitmapScalerIWICBitmapClipperIWICBitmapFlipRotatorIWICFormatConverter) 来执行帧解码器对 CopyPixels 调用的结果无法执行的剩余转换。 如果解码器不支持 IWICBitmapSourceTransform,则 WIC 必须使用转换对象来执行所有转换。 解码器在解码过程中执行转换通常比解码整个图像然后执行转换要高效得多。 对于缩放到更小的大小或像素格式转换等操作尤其如此。

interface IWICBitmapSourceTransform : IUnknown
{
   // Required methods
   HRESULT DoesSupportTransform ( WICTransformOptions dstTransform,
              BOOL *pfIsSupported);
   HRESULT CopyPixels ( WICRect *prcSrc, 
      UINT uiWidth, 
      UINT uiHeight,
      WICPixelFormatGUID * pguidDstFormat,
      WICBitmapTransformOptions dstTransform, 
      UINT nStride, 
      UINT cbBufferSize, 
      BYTE *pbBuffer );

   // Optional methods
   HRESULT GetClosestSize ( UINT *puiWidth,
              UINT *puiHeight);
   HRESULT GetClosestPixelFormat ( WICPixelFormatGUID *pguidDstFormat);
}

DoesSupportTransform

DoesSupportTransform 询问解码器是否支持请求的旋转或翻转操作。 可能请求的 WICBitmapTransformOptions 为:

enum WICBitmapTransformOptions
{   
   WICBitmapTransformRotate0,
   WICBitmapTransformRotate90,
   WICBitmapTransformRotate180,
   WICBitmapTransformRotate270,
   WICBitmapTransformFlipHorizontal,
   WICBitmapTransformFlipVertical
}

CopyPixels

CopyPixels 执行图像位解码的实际工作,例如 IWICBitmapSource 接口上的 CopyPixels 方法,但 IWICBitmapSourceTransform 上的 CopyPixels 方法更强大,并且可以显著提高图像处理性能。

请求多个转换操作时,结果取决于操作的执行顺序。 为了确保编解码器之间的可预测性和一致性,所有编解码器必须以相同的顺序执行这些操作。 这是执行这些操作的规范顺序。

  1. 缩放
  2. Crop
  3. 旋转

可以随时执行像素格式转换,因为它不会影响其他转换。

第一个参数 prcSrc 用于指定剪裁图像所需的区域。 由于缩放是在按约定进行剪裁之前执行的,因此如果要缩放和剪裁图像,则应在缩放图像后确定感兴趣的区域。

第二个和第三个参数指示缩放图像的大小。

pguidDstFormat 参数指示解码图像的请求像素格式。 由于 WIC 已调用 GetClosestPixelFormat,因此这应该是解码器已指示其支持的像素格式。

dstTransform 参数指示请求的旋转角度,以及是垂直翻转还是水平翻转图像,还是同时翻转两者。 同样,由于 WIC 已调用 DoesSupportTransform,因此请求的转换应该是解码器已指示其支持的转换。 请记住,应在缩放和剪裁后始终执行旋转。

GetClosestSize

GetClosestSize 采用两个 in/out 参数。 调用方使用 puiWidthpuiHeight 参数来指定调用方首选解码图像的大小。 但是,解码器只能将图像解码为其 DCT 大小的倍数,并且不同的图像格式可以具有不同的 DCT 大小。 解码器应根据其自己的 DCT 大小确定它最接近请求的大小,并在返回时将 puiWidthpuiHeight 设置为这些维度。 如果请求更大的大小,但编解码器不支持向上缩放,则应返回原始。

GetClosestPixelFormat

GetClosestPixelFormat 用于确定最接近请求的像素格式,解码器可以在不丢失数据的情况下提供该格式。 转换为更宽的像素格式比较窄的像素格式总是可取的,即使它会增加图像的大小,因为如果需要,它始终可以重新转换为限制性更高的格式。 但是,数据丢失后无法恢复。

继续阅读

若要详细了解如何创建已启用 WIC 的编解码器,请参阅 实现 IWICDevelopRaw

参考

IWICBitmapSourceTransform

IWICMetadataBlockReader

概念性

实现 IWICMetadataBlockReader

实现 IWICDevelopRaw

如何编写WIC-Enabled编解码器

Windows 映像组件概述