如果您想要控制,请使用Windows Imaging Component。您需要创建一个Decoder 并检索您感兴趣的image frame(s)。PNG Format Overview 概述了 PNG 支持。
以下示例代码打开一个灰度 PNG 图像,并显示有关媒体的信息:
#include <windows.h>
#include <wincodec.h>
#pragma comment(lib, "Windowscodecs.lib")
#include <iostream>
int main() {
::CoInitialize( NULL );
创建工厂 COM 服务器:
IWICImagingFactory* pFactory = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(void**)&pFactory );
根据图片源创建解码器:
IWICBitmapDecoder* pDecoder = NULL;
if ( SUCCEEDED( hr ) ) {
hr = pFactory->CreateDecoderFromFilename( L"test.png",
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand,
&pDecoder );
}
虽然 PNG 文件总是包含一个图像,但也有一些图像格式允许将多个图像存储在一个文件中。一般来说,您必须查询帧数并遍历所有帧,一个接一个地解码:
UINT frameCount = 0;
if ( SUCCEEDED( hr ) ) {
hr = pDecoder->GetFrameCount( &frameCount );
}
if ( SUCCEEDED( hr ) ) {
std::wcout << L"Framecount: " << frameCount << std::endl;
for ( UINT frameIndex = 0; frameIndex < frameCount; ++frameIndex ) {
std::wcout << std::endl << L"Frame " << frameIndex << L":" << std::endl;
IWICBitmapFrameDecode* pFrame = NULL;
hr = pDecoder->GetFrame( frameIndex, &pFrame );
出于说明目的转储图像尺寸:
if ( SUCCEEDED( hr ) ) {
UINT width = 0, height = 0;
hr = pFrame->GetSize( &width, &height );
if ( SUCCEEDED( hr ) ) {
std::wcout << L" width: " << width <<
L", height: " << height << std::endl;
}
}
要验证图像数据是否未被更改,请转储 bpp 和通道计数信息:
if ( SUCCEEDED( hr ) ) {
WICPixelFormatGUID pixelFormat = { 0 };
pFrame->GetPixelFormat( &pixelFormat );
if ( SUCCEEDED( hr ) ) {
// Translate pixelformat to bpp
IWICComponentInfo* pComponentInfo = NULL;
hr = pFactory->CreateComponentInfo( pixelFormat, &pComponentInfo );
IWICPixelFormatInfo* pPixelFormatInfo = NULL;
if ( SUCCEEDED( hr ) ) {
hr = pComponentInfo->QueryInterface( &pPixelFormatInfo );
}
UINT bpp = 0;
if ( SUCCEEDED( hr ) ) {
hr = pPixelFormatInfo->GetBitsPerPixel( &bpp );
}
if ( SUCCEEDED( hr ) ) {
std::wcout << L" bpp: " << bpp << std::endl;
}
UINT channelCount = 0;
if ( SUCCEEDED( hr ) ) {
hr = pPixelFormatInfo->GetChannelCount( &channelCount );
}
if ( SUCCEEDED( hr ) ) {
std::wcout << L" Channel Count: " << channelCount << std::endl;
}
// Cleanup
if ( pPixelFormatInfo != NULL ) { pPixelFormatInfo->Release(); }
if ( pComponentInfo != NULL ) { pComponentInfo->Release(); }
}
}
剩下的就是资源清理:
// Cleanup
if ( pFrame != NULL ) { pFrame->Release(); }
}
}
// Cleanup
if ( pDecoder != NULL ) { pDecoder->Release(); }
if ( pFactory != NULL ) { pFactory->Release(); }
return 0;
}
针对这张图片运行这段代码
产生以下输出:
Framecount: 1
Frame 0:
width: 50, height: 50
bpp: 8
Channel Count: 1