JPEGやPNGのメタ情報をAPIで取得する方法(Windows Imaging Component)

先日のネタに引き続き、画像フォーマットを知らなくても出来る!画像ファイルのEXIF, XMPメタ情報の取得方法を紹介します。
音楽と違ってメタ情報をクエリする為の文字列が難しくて、結局その画像のメタ情報に詳しくならないと意味がないという謎APIですが、自力解析よりは楽でしょう。
利用するのはWindows Imaging Componentです。追加インストールしたらXPでも利用出来ますし、Vista以降は標準搭載です。しかもユーザが拡張できちゃう優れもの。
結局、エクスプローラで取得できる画像情報は全てこのAPIで取得出来ます。利用する関数は、WICBitmapFrameDecodeとGetMetadataQueryReaderです。
以下サンプルでは、画像がどんなソフトウェアで作られたかを解析し、一時変数に代入します。

#include <windows.h>
#include <wincodec.h>
#include <wincodecsdk.h>
#include <strsafe.h>
#include <Propvarutil.h>

#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "WindowsCodecs.lib")
#pragma comment(lib, "PropSys.lib") // XPで使えない

_COM_SMARTPTR_TYPEDEF(IEnumString, __uuidof(IEnumString));
_COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder, __uuidof(IWICBitmapDecoder));
_COM_SMARTPTR_TYPEDEF(IWICBitmapSource, __uuidof(IWICBitmapSource));
_COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode, __uuidof(IWICBitmapFrameDecode));
_COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
_COM_SMARTPTR_TYPEDEF(IWICMetadataQueryReader, __uuidof(IWICMetadataQueryReader));

void GetImageFileInfo(LPCWSTR lpwzFileName)
{
 IWICBitmapDecoderPtr spDecoder;
 IWICImagingFactoryPtr spFactory;
 if(SUCCEEDED(spFactory.CreateInstance(CLSID_WICImagingFactory))) {
  if(SUCCEEDED(spFactory->CreateDecoderFromFilename(lpwzFileName, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &spDecoder))) {
   IWICBitmapFrameDecodePtr pFrame;
   if(SUCCEEDED(spDecoder->GetFrame(0, &pFrame))) {
    IWICMetadataQueryReaderPtr pReader;
    if(SUCCEEDED(pFrame->GetMetadataQueryReader(&pReader))) {
     // Software
     // System.ApplicationName Photo Metadata Policy
     // Output : VT_LPWSTR
     PropVariantInit(&val);
     if(SUCCEEDED(pReader->GetMetadataByName(L"/app1/ifd/exif/{ushort=305}", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/ifd/iptc/Originating Program", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/app13/irb/8bimiptc/iptc/Originating Program", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/xmp/xmp:CreatorTool", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/xmp/xmp:creatortool", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/xmp/tiff:Software", &val)) ||
      SUCCEEDED(pReader->GetMetadataByName(L"/xmp/tiff:software", &val)))
     {
      //_ASSERT(val.vt == VT_LPWSTR);
      WCHAR wszSoftware[256]; // For Test
      PropVariantToString(val, wszSoftware, ARRAYSIZE(wszSoftware));
      PropVariantClear(&val);
     }
    }
   }
  }
 }
}

厄介なのはPropVariantのデコードが標準的なXPでは出来ない(PropVariantToStringが使えない)ってことですが、MSDNを見たら自力でデコーダを作れます。画像にどんなメタ情報が入っているか全て列挙するのは、IEnumStringです。はっきりいって自力解析できるものではないです。
WICは画像フォーマットの自動判別&ユーザプラグイン追加に勝手に対応するのが嬉しいですね。

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz