WIC 対応コーデックの作成方法
自社のイメージ形式に対する完全なプラットフォーム サポートの確保
更新日: 2009 年 4 月 28 日
ダウンロード
PDC08_How_to_Write_a_WIC-Enabled_CODEC-PDC08-001_JPN.doc (Word 形式、397 KB)
目次:
はじめに
Windows Imaging Component のしくみ
- 検出と判別
- デコード
- エンコード
- コーデックの有効期間
- コーデックを WIC 対応にする方法
- WIC でのマルチスレッド アパートメントのサポート
WIC 対応デコーダーの実装
デコーダー インターフェイス
- IWICBitmapDecoder
- IWICBitmapCodecProgressNotification
- IWICBitmapSource
- IWICBitmapFrameDecode
- IWICMetadataBlockReader
- IWICBitmapSourceTransform
- IWICDevelopRaw
WIC 対応エンコーダーの実装
エンコーダー インターフェイス
- IWICBitmapEncoder
- IWICBitmapProgressNotification
- IWICBitmapFrameEncode
- IWICMetadataBlockWriter
コーデックのインストールと登録
- コーデックの登録
- コーデック インストール時の縮小表示キャッシュの更新
- WIC 対応コーデックのユーザーへの提供
まとめ
詳細情報
Dave Wilson
Michael Bourgoin
Varun Bhartia
Robert Wlodarczyk
Microsoft Corporation
2008 年 9 月
対象:
Windows Imaging Component (WIC)
要約:
Windows Imaging Component (WIC) フレームワーク内で機能するイメージ ファイル形式コーデックを実装する方法について、開発者向けにガイダンスを提供します。
法的通知:
このドキュメントは暫定版であり、このソフトウェアの最終的な製品版の発売時に実質的に変更されることがあります。
このドキュメントに記載されている情報は、このドキュメントの発行時点におけるマイクロソフトの見解を反映したものです。変化する市場状況に対応する必要があるため、このドキュメントは、記載された内容の実現に関するマイクロソフトの確約とはみなされないものとします。また、発行以降に発表される情報の正確性に関して、マイクロソフトはいかなる保証もいたしません。
このホワイト ペーパーに記載された内容は情報の提供のみを目的としており、明示、黙示または法律の規定にかかわらず、これらの情報についてマイクロソフトはいかなる責任も負わないものとします。
お客様ご自身の責任において、適用されるすべての著作権関連法規に従ったご使用を願います。このドキュメントのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受けることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。ここでいう形態とは、複写や記録など、電子的な、または物理的なすべての手段を含みます。ただしこれは、著作権法上のお客様の権利を制限するものではありません。
マイクロソフトは、このドキュメントに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有する場合があります。別途マイクロソフトのライセンス契約上に明示の規定のない限り、このドキュメントはこれらの特許、商標、著作権、またはその他の無体財産権をお客様に許諾するものではありません。
別途記載されていない場合、このソフトウェアおよび関連するドキュメントで使用している会社、組織、製品、ドメイン名、電子メール アドレス、ロゴ、人物、場所、出来事などの名称は架空のものです。実在する商品名、団体名、個人名などとは一切関係ありません。
© 2008 Microsoft Corporation. All rights reserved.
Microsoft、MS-DOS、Windows、Windows NT、Windows Server、Windows Vista、Active Directory、ActiveSync、ActiveX、Direct3D、DirectDraw、DirectInput、DirectMusic、DirectPlay、DirectShow、DirectSound、DirectX、Expression、FrontPage、HighMAT、Internet Explorer、JScript、Microsoft Press、MSN、Outlook、PowerPoint、SideShow、Silverlight、Visual Basic、Visual C++、Visual InterDev、Visual J++、Visual Studio、WebTV、Windows Media、Win32、Win32s、および Zune は米国 Microsoft Corporation の米国またはその他の国における登録商標または商標です。
記載されている会社名、製品名には、各社の商標のものもあります。
1. はじめに
Windows® Imaging Component (WIC) は、Windows Vista および Windows 7 オペレーティング システムのデジタル イメージング用の拡張可能なプラットフォームです。また、WIC は、.NET 3.0 のコンポーネントまたは再配布可能な独立したコンポーネントとして、Windows XP および Windows Server® 2003 でも使用できます。WIC を使用するアプリケーションは、WIC 対応のコーデックを提供するイメージ形式であればどのイメージ形式でも、各形式に関する特定の知識を必要としない一貫性のある一連のインターフェイスを使用して、イメージのアクセス、表示、処理、および印刷が可能です。
Windows Vista のエクスプローラ、Windows Vista フォト ギャラリー、Windows Live フォト ギャラリー、Windows 7 フォト ビューアーは、WIC を基盤としています。そのため、Vista システムに WIC 対応のコーデックをインストールしておけば、このコーデックに関連付けられているイメージ形式に対して、Windows Vista に付属の標準イメージ形式と同等のサポートが得られます。開発したイメージ形式のコーデックを自社で作成するため、イメージ形式が使用される場所に関係なく一貫した品質を保証できます。また、自社の IP 投資を保護しながら、完全なプラットフォーム サポートを確保できるというメリットがあります。
ページのトップへ
2. Windows Imaging Component のしくみ
a. 検出と判別
イメージをデコードするには、まずそのイメージ形式をデコードできる適切なコーデックを見つける必要があります。ほとんどのシステムでは、サポートされるイメージ形式はハード コーディングされているため、検出処理は必要ありません。ただし、WIC プラットフォームは拡張可能なので、イメージの形式を識別して適切なコーデックに対応付けることができる必要があります。
実行時の検出をサポートするには、各イメージ形式にその形式に適したデコーダーの識別に使用できる識別パターンが含まれている必要があります (新しいファイル形式の場合は、識別パターンに GUID を使用することを強くお勧めします。これにより確実に識別パターンを一意にすることができます)。識別パターンは、そのイメージ形式と互換性のある各イメージ ファイルに埋め込まれている必要があります。各デコーダーには、デコードできるイメージ形式の識別パターンを指定するレジストリ エントリがあります。アプリケーションはイメージを開く前に、WIC にデコーダーを要求します。WIC は、使用できるデコーダーをレジストリ内で検索し、各レジストリ エントリを調べてイメージ ファイルに埋め込まれたパターンと一致する識別パターンを探します。この詳細については、「デコーダー固有のレジストリ エントリ」で説明します。
イメージの識別パターンと一致するデコーダーが 1 つだけ見つかった場合は、このデコーダーのインスタンスを作成し、イメージ ファイルを渡します。一致するパターンが複数見つかった場合は、パターンが一致する各デコーダーの QueryCapability メソッドを呼び出し、これらのデコーダーを対象に判別を行い、最適なデコーダーを決定します。この詳細については、IWICBitmapDecoder インターフェイスの QueryCapability メソッドで説明します。
ページのトップへ
b. デコード
適切なデコーダーが選択されインスタンスが作成されると、アプリケーションは直接デコーダーと通信します。デコーダーには、さまざまなインターフェイスによって実装されるいくつかのサービスがあります。これらのサービスは次のように分類できます。
- コンテナー レベルのサービス
- フレーム レベルのサービス
- メタデータ列挙サービス
- デコーダーのネイティブ変換
- 進行状況の通知とキャンセルのサポート
- RAW イメージの処理サービス
コンテナー レベルのサービスでは、最上位レベルのサムネイル (サポートされる場合)、プレビュー、カラー コンテキスト、パレット (該当する場合)、およびコンテナー形式が取得されるほか、コンテナー内の個々のイメージ フレームへのアクセスが提供されます (コンテナーには、単一のフレームしかないものもあれば、たとえば TIFF 形式のように複数のフレームを含むものもあります)。また、デコーダー自体に関する情報や、特定のイメージ ファイルに関係するデコーダー機能も提供されます。
個々のフレームには独自のサムネイルがあるほか、フレーム レベルで表示される独自のカラー コンテキストやパレットなども含まれる場合があります。ただし、フレーム レベルで実行される最も重要な操作は、フレームのイメージ ビットの実際のデコードです。
WIC では、最も一般的なメタデータ形式 (IFD、EXIF、IPTC、XMP、APP0、APP1 など) 用のメタデータ リーダーが提供され、サード パーティのメタデータ形式向けの拡張機能もサポートされます。その結果、コーデックによりメタデータを解析する必要はなくなりますが、メタデータ ブロックの列挙や、ブロックごとにメタデータ リーダーを要求する必要はあります。WIC は、メタデータ ハンドラーのレジストリ エントリのパターンと一致する、ブロック ヘッダー内のパターンを基に、コーデックと同様の方法でメタデータ ハンドラーを検索します。この詳細については、「コーデックのインストールと登録」の「デコーダー固有のレジストリ エントリ」で説明します。
デコーダーでは、変換操作をネイティブにサポートする必要はありませんが、サポートすると、パフォーマンスを大幅に最適化でき、ユーザー エクスペリエンスが向上します。たとえば、アプリケーションでさまざまな変換 (スケール変換、トリミング、回転、ピクセル形式の変換) のパイプラインを作成し、イメージを表示する前に変換を実行できます (変換パイプラインの詳細については、「IWICBitmapSource」で説明します)。アプリケーションで変換パイプラインを作成した後、パイプラインの最後の変換が要求されると、イメージ ソースにすべての変換を適用した結果のビットマップが作成されます。この時点で、デコーダー自体が変換操作を実行できる場合、WIC は要求された変換のうちデコーダーで実行できる変換をデコーダーに依頼します。要求された変換のうちデコーダーで実行できないものはすべて、WIC によってデコードされたイメージに対して実行され、変換されたイメージが呼び出し元に返されます。変換のパイプラインをこのように最適化することで、特に変換の一部またはすべてをデコード処理中に完了できる場合は、メモリ内で各変換を順次実行するよりもパフォーマンスが向上します。
RAW イメージの処理サービスでは、未加工のイメージ ビットを処理する前に、露出、コントラスト、シャープなどのカメラ設定の微調整や、色空間の変更を実行できます。
進行状況の通知とキャンセルのサポートによって、時間がかかる操作の進行状況の通知をアプリケーションから要求できます。また、このサポートによって、時間がかかりすぎる操作をキャンセルする機会をアプリケーションからユーザーに提供できます。操作をキャンセルできない場合、ユーザーは処理がハングしていると見なし、アプリケーションを終了することで処理をキャンセルすることがあるため、このようなサポートは重要です。
これらのインターフェイスの詳細については、「WIC 対応デコーダーの実装」で説明します。
ページのトップへ
c. エンコード
デコーダーと同様、エンコーダーにもインターフェイスによって実装する機能があります。エンコーダーが提供するサービスは、デコーダーによって提供されるサービスを補完するものですが、イメージ データの読み取りではなく、書き込みを行います。エンコーダーでは、次のカテゴリのサービスを提供します。
- コンテナー レベルのサービス
- フレーム レベルのサービス
- メタデータ列挙サービスと更新サービス
- 進行状況の通知とキャンセルのサポート
エンコーダーのコンテナー レベルのサービスには、最上位レベルのサムネイル (サポートされる場合)、プレビュー、パレット (該当する場合) の設定、コンテナーにイメージ フレームをシリアル化するための、個別のイメージ フレームの反復処理などがあります。
エンコーダーのフレーム レベルのサービスは、デコーダーのフレーム レベルのサービスと同じ構成ですが、イメージ データ、サムネイル、すべての関連するパレットなどを読み取るのではなく、書き込みを行います。
同様に、エンコーダーのメタデータ列挙サービスには、書き込まれるメタデータ ブロックの反復処理、メタデータをディスクにシリアル化するための適切なメタデータ ライターの呼び出しなどがあります。
これらのインターフェイスの詳細については、「WIC 対応エンコーダーの実装」で説明します。
ページのトップへ
d. コーデックの有効期間
WIC コーデックでは、1 つのイメージだけを処理するためにインスタンスが作成されるので、通常有効期間は短期間です。インスタンスはイメージが読み込まれるときに作成され、イメージが閉じられるときに解放されます。アプリケーションでは、有効期間が重複した状態で大量のコーデックを同時に使用する場合 (何百ものイメージを含むディレクトリをスクロールする場合など) や、さらには複数のアプリケーションがこの処理を同時に実行する場合があります。
これまでは、有効期間がそのコーデックが存在するプロセスの有効期間に設定されるように、コーデックが作成されている場合がありました。しかし、このようなことは WIC コーデックでは行いません。Windows® Vista のフォト ギャラリーやエクスプローラを始めとする多数のアプリケーションは WIC を基に構築されます。このようなアプリケーションでは、各開発者によるコーデックを使用してイメージやサムネイルを表示します。コーデックの有効期間がプロセスの有効期間に設定されていると、イメージやサムネイルが Windows Vista のエクスプローラで表示されるたびに、そのイメージをデコードするためのコーデックのインスタンスが作成され、これらのインスタンスはユーザーが次回コンピュータを再起動するまでメモリに残ります。コーデックがアンロードされることがないと、システムの他のすべてのコンポーネントがこのコーデックのリソースを使用できないため、事実上、そのリソースは "リーク" していることになります。
ページのトップへ
e. コーデックを WIC 対応にする方法
コーデックを WIC 対応にするには、次の手順を実行します。
- イメージのデコードとメタデータ ブロックの反復処理に必要な WIC インターフェイスを公開する、コンテナー レベルのデコーダー クラスとフレーム レベルのデコーダー クラスを実装します。これにより、すべての WIC ベースのアプリケーションは、標準のイメージ形式とまったく同じように各開発者のコーデックを操作できます。
- イメージのエンコードとメタデータのブロックをイメージ ファイルにシリアル化するために必要な WIC インターフェイスを公開する、コンテナー レベルのエンコーダー クラスとフレーム レベルのエンコーダー クラスを実装します。
- コンテナー形式が TIFF コンテナーまたは JPEG コンテナーを基盤としていない場合は、共通のメタデータ形式 (EXIF、XMP) 用にメタデータ ハンドラーの作成が必要になることがあります。ただし、標準の IFD または IRB を使用して EXIF または XMP メタデータを格納する場合は、システムで用意されている IFD または IRB 用のメタデータ ハンドラーに委任できるため、ハンドラーを作成する必要はありません。また、TIFF コンテナーまたは JPEG コンテナーを基盤としないコンテナー形式の場合は、専用の IPropertyStore インターフェイス実装を提供する必要があります (ほとんどのコーデック作成者は独自のメタデータ ハンドラーを実装する必要はないため、このホワイト ペーパーではメタデータ ハンドラーの作成方法については説明しません)。
- すべてのイメージ ファイルに一意な識別パターン (GUID を推奨) を埋め込みます。これにより、検出時に各イメージ形式が専用のコーデックに対応付けられます (既存のイメージ形式用に WIC ラッパーを作成している場合、なんらかのビット パターンを見つけて、これを識別パターンとして使用する必要があります。このビット パターンはそのイメージ形式に対して一意になるもので、エンコーダーは常にこの形式のイメージ ファイルにこのビット パターンを書き込みます)。通常、一意なパターンは、ファイルの先頭数バイトに存在します。このパターンは、ファイルのヘッダーの先頭数バイト内に配置し、コーデックがストリームを必要以上に読み取らなくてもよいようにすることをお勧めします。ただし、パターンをファイルのヘッダーに配置できない場合、WIC では、ストリームの最後以降のオフセットも含めて、ファイル内の任意の場所にパターンを登録できます。
- インストール時にコーデックを登録します。これにより、レジストリ内の識別パターンとイメージ ファイルに埋め込まれたパターンとが対応付けられ、実行時にコーデックが検出されます。
- Windows® 7 では、WIC 対応コーデックは、COM アパートメントの種類が "Both" である必要があります。つまり、アパートメントをまたいだ呼び出しを行う呼び出し元と、マルチスレッド シナリオでの呼び出し元を処理するために、適切なロックを行う必要があります。詳細については、「WIC でのマルチスレッド アパートメントのサポート」を参照してください。
重要: このホワイト ペーパーのインターフェイスに関する説明では、メソッドに "必須" と記載している場合は必ず、そのメソッドの完全な実装が必要であることを意味します。メソッドに "省略可能" と記載している場合でも、インターフェイスを実装するクラスにそのメソッドを含める必要があります。ただし、実際に実装しないで、適切なエラー コードを返すだけでもかまいません。
メソッドによっては、特定のエラー コードを返して、要求された機能がサポートされていないことを呼び出し元に通知する必要があります。たとえば、グローバル サムネイルをサポートしない場合は、GetThumbnail メソッドから WINCODEC_ERR_CODECNOTHUMBNAIL を返す必要があります。エンコードまたはデコードするイメージがインデックス付きピクセル形式を使用していない場合、またはコンテナー レベルのパレットをサポートしていない場合は、SetPalette メソッドから WINCODEC_ERR_PALETTEUNAVAILABLE を返す必要があります。その他のサポートしていないメソッドについては、WINCODEC_ERR_UNSUPPORTEDOPERATION を返します。
このホワイト ペーパーのサンプル コードをご自身のコーデックに使用される場合は、エラー チェックと参照カウントがサンプル コードには含まれていないことにご注意ください。
ページのトップへ
f. WIC でのマルチスレッド アパートメントのサポート
マルチスレッド アパートメント (MTA) 内のオブジェクトは、その MTA 内のいくつのスレッドからでも同時に呼び出すことができます。このため、マルチコア システムや特定のサーバー シナリオでは、パフォーマンスが向上します。また、MTA 内の WIC コーデックは、異なる STA アパートメントのスレッド間での呼び出しに伴うマーシャリング コストが発生することなく、同じ MTA 内の他のオブジェクトを呼び出すことができます。Windows 7 では、JPEG、TIFF、PNG、GIF、ICO、BMP など、付属の WIC コーデックはすべて MTA をサポートするように更新されています。サードパーティのコーデックも MTA をサポートするように作成されることを強くお勧めします。MTA をサポートしないサードパーティのコーデックは、マーシャリングのために、マルチスレッド アプリケーションにかなりのパフォーマンス コストをかけることになります。MTA をサポートするには、サードパーティのコーデックに適切な同期が実装される必要があります。このような同期手法の具体的な実装については、ここでは取り上げませんが、COM オブジェクトの同期に関する概要については、「Understanding and Using COM Threading Models」(英語) を参照してください。
ページのトップへ
3. WIC 対応デコーダーの実装
WIC デコーダーを実装するには、2 つのクラスを作成する必要があります。これらのクラスのインターフェイスは、上記の「Windows Imaging Component のしくみ」の「デコード」で説明したデコーダーの機能に直接対応しています。
これらのクラスのうちの 1 つは、コンテナー レベルのサービスを提供し、IWICBitmapDecoder インターフェイスを実装します。イメージ形式がコンテナー レベルのメタデータをサポートする場合、このクラスに IWICMetadataBlockReader インターフェイスも実装する必要があります。ユーザー エクスペリエンスを向上するために、デコーダーとエンコーダーの両方で IWICBitmapCodecProgressNotification インターフェイスをサポートすることをお勧めします。
もう 1 つのクラスはフレーム レベルのサービスを実装し、コンテナー内の各フレームのイメージ ビットを実際にデコードします。このクラスでは、IWICBitmapFrameDecode インターフェイスと IWICMetadataBlockReader インターフェイスを実装します。カメラの RAW 形式用のデコーダーを作成している場合は、このクラスに IWICDevelopRaw インターフェイスも実装する必要があります。また、これらの必須インターフェイスに加えて IWICBitmapSourceTransform インターフェイスを実装し、イメージ形式のパフォーマンスを最大限引き出せるようにすることを強くお勧めします。
イメージ形式がプログレッシブ デコードをサポートする場合は、フレーム レベルのサービス クラスに IWICProgressiveLevelControl インターフェイスも実装する必要があります。
WIC が提供するオブジェクトの 1 つに ImagingFactory があります。さまざまなコンポーネントを作成するために、このオブジェクトの IWICComponentFactory インターフェイスを頻繁に使用することになります。この ImagingFactory インターフェイスは頻繁に使用することになるため、このインターフェイスへの参照をデコーダー クラスとエンコーダー クラスの両方のメンバー プロパティとして保持しておくことをお勧めします。
IWICImagingFactory* m_piImagingFactory = NULL;
IWICComponentFactory* m_piComponentFactory = NULL;
HRESULT hr;
hr = CoCreateInstance(CLSID_WICImagingFactory, NULL,
CLSCTX_INPROC_SERVER, IID_IWICImagingFactory,
(LPVOID*) m_piImagingFactory);
hr = m_piImagingFactory->QueryInterface(
IID_IWICComponentFactory, (void**)&m_piComponentFactory);
a. デコーダー インターフェイス
次の表に WIC デコーダーによって実装されるインターフェイスを示します。また、この後のクラス図では、継承階層を示します。
インターフェイス |
機能 |
実装 |
IWICBitmapDecoder |
コンテナー レベルのサービス |
必須 |
IWICBitmapCodecProgressNotification |
進行状況の通知とキャンセルのサポート |
推奨 |
IWICMetadataBlockReader |
メタデータの列挙 |
省略可能 (コンテナー レベルのメタデータをサポートする形式のみ必須) |
インターフェイス |
機能 |
実装 |
IWICBitmapFrameDecode |
フレーム レベルのサービス |
必須 |
IWICMetadataBlockReader |
メタデータの列挙 |
必須 |
IWICBitmapSourceTransform |
デコーダーのネイティブ変換 |
コーデックがネイティブ変換をサポートする場合は必須。サポートしない場合は、今後の改訂時に、ネイティブ変換をサポートするようにイメージ ファイル形式を更新することを検討してください。 |
IWICProgressiveLevelControl |
プログレッシブ デコード |
イメージ ファイル形式とコーデックが、プログレッシブ デコードをサポートする場合は必須 |
IWICDevelopRaw |
RAW イメージの処理サービス |
カメラの RAW 形式のみ必須 |
IWIDDevelopRawNotificationCallBack |
RAW イメージ パラメーターの変更通知に使用されるアプリケーション定義のコールバック メソッド |
カメラの RAW コーデックには必須 |
- IWICBitmapDecoder
- IWICBitmapCodecProgressNotification
- IWICBitmapSource
- IWICBitmapFrameDecode
- IWICMetadataBlockReader
- IWICBitmapSourceTransform
- IWICDevelopRaw
ページのトップへ
1. IWICBitmapDecoder
アプリケーションがデコーダーを要求するとき、コーデックとの通信は、まず IWICBitmapDecoder インターフェイス経由で行います。これはコンテナー レベルのインターフェイスで、コンテナーと、コンテナーに含まれる最も重要なフレームの最上位レベルのプロパティへのアクセスを提供します。これは、コンテナー レベルのデコーダー クラスの主インターフェイスです。
interface IWICBitmapDecoder : IUnknown
{
// 必須のメソッド
HRESULT QueryCapability ( IStream *pIStream,
DWORD *pdwCapabilities );
HRESULT Initialize ( IStream *pIStream,
WICDecodeOptions cacheOptions );
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetDecoderInfo ( IWICBitmapDecoderInfo **pIDecoderInfo );
HRESULT GetFrameCount ( UINT *pCount );
HRESULT GetFrame ( UINT index,
IWICBitmapFrameDecode **ppIBitmapFrame );
// 省略可能なメソッド
HRESULT GetPreview ( IWICBitmapSource **ppIPreview );
HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
HRESULT GetColorContexts ( UINT cCount,
IWICColorContext **ppIColorContexts,
UINT *pcActualCount );
HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader **ppIMetadataQueryReader );
HRESULT CopyPalette ( IWICPalette *pIPalette );
}
イメージ形式の中にはグローバルなサムネイル、カラー コンテキスト、メタデータが含まれるものもありますが、多くのイメージ形式ではこれらをフレーム単位でしか提供しません。そのため、これらにアクセスするメソッドは IWICBitmapDecoder では省略できますが、IWICBitmapFrameDecode では必須です。同様に、一部のコーデックではインデックス付きピクセル形式を使用しないため、どちらのインターフェイスにも CopyPalette メソッドを実装する必要はありません。IWICBitmapDecoder の省略可能なメソッドについては、IWICBitmapFrameDecode で説明します。IWICBitmapFrameDecode は、これらのメソッドを実装することが最も多いインターフェイスです。
QueryCapability は、コーデックの判別に使用するメソッドです (このホワイト ペーパー冒頭の「Windows Imaging Component のしくみ」の「検出と判別」を参照してください)。このメソッドは、2 つのコーデックで同じイメージ形式をデコードできる場合、または 2 つのコーデックが偶然同じ識別パターンを使用しているというパターンの競合が発生した場合、特定のイメージに最も適した処理を実行できるコーデックを選択できるようにするため、非常に重要なメソッドです。
このメソッドを呼び出すと、WIC からイメージを含む実際のストリームが渡されます。デコーダーに渡された特定のファイル ストリームに関連があるデコーダーの機能を正しく宣言するために、イメージ内の各フレームをデコードして、メタデータ ブロック全体を列挙できるかどうかを確認するのはコーデック作成者の役割です。このことはすべてのデコーダーにとって重要ですが、TIFF コンテナー ベースのイメージ形式にとっては特に重要です。検出処理は、レジストリ内のデコーダーに関連付けられたパターンを、実際のイメージ ファイルのパターンと照合することで機能します。レジストリに識別パターンを宣言することで、対象の形式のイメージのデコーダーが常に検出されることは保証されますが、他の形式のイメージのデコーダーが検出されないことは保証されません。たとえば、すべての TIFF コンテナーには TIFF パターンが含まれています。これは TIFF イメージ形式に対して有効な識別パターンです。つまり、検出中に、TIFF スタイルのコンテナーを基盤とした任意の形式のイメージ ファイルで、少なくとも 2 つの識別パターンが見つかります。1 つは TIFF パターン、もう 1 つは実際のイメージ形式のパターンです。あまり頻繁には発生しませんが、他の関連のないイメージ形式間でもパターンの競合が発生することがあります。このため、検出と判定は 2 段階で処理されます。QueryCapabilities に渡されたイメージのストリームが、実際に自社のイメージ形式にとって有効なインスタンスであることを常に確認してください。また、自社のコーデックが独自の仕様のないイメージ形式をデコードする場合、QueryCapabilities の実装によって、コーデックが実装しないイメージ形式仕様の下で有効になる可能性のあるすべての機能の存在を調べる必要があります。これにより、確実にそのコーデックのユーザー エクスペリエンスが向上し、不要なデコード エラーが発生したり、予期しない結果が返されることがなくなります。
イメージになんらかの操作を実行する前に、ストリームの現在位置を保存する必要があります。現在位置を保存しておくと、メソッドから返る前の元の位置にストリームを復元できます。
デコーダーの機能を指定する列挙値は、次のように定義されます。
enum WICBitmapDecoderCapabilities
{ WICBitmapDecoderCapabilitySameEncoder,
WICBitmapDecoderCapabilityCanDecodeAllImages,
WICBitmapDecoderCapabilityCanDecodeSomeImages,
WICBitmapDecoderCapabilityCanEnumerateMetadata,
WICBitmapDecoderCapabilityCanDecodeThumbnail }</code></pre>
イメージが各開発者のエンコーダーでエンコードされた場合は、WICBitmapDecoderCapabilitySameEncoder のみを宣言します。コンテナー内の各フレームをデコードできるかどうかを確認したら、デコードできないフレームが存在する場合は WICBitmapDecoderCapabilityCanDecodeSomeImages を、すべてのフレームをデコードできる場合は WICBitmapDecoderCapabilityCanDecodeAllImages を宣言し、まったくデコードできない場合はどちらも宣言しません (これら 2 つの列挙値は同時に宣言できません。WICBitmapDecoderCapabilityCanDecodeAllImages を返すと、WICBitmapDecoderCapabilityCanDecodeSomeImages は無視されます)。イメージのコンテナー内のメタデータ ブロックを列挙できることを確認したら、WICBitmapDecoderCapabilityCanEnumerateMetadata を宣言します。すべてのフレーム内のサムネイルを調べる必要はありません。グローバル サムネイルがあり、それをデコードできる場合は WICBitmapDecoderCapabilityCanDecodeThumbnail を宣言できます。グローバル サムネイルがない場合は、フレーム 0 のサムネイルのデコードを試します。どこにもサムネイルがない場合は、この機能は宣言しません。
このメソッドに渡されたイメージのストリームについてのデコーダーの機能を決定したら、このイメージに対してこのデコーダーを実行できることを確認したことを示す WICBitmapDecoderCapabilities を、論理演算子 OR (|) で結合して指定し、結果を返します。このとき、結果を返す前に忘れずに、元の位置にストリームを復元してください。
Initialize は、特定のイメージをデコードするデコーダーが選択された後で、アプリケーションから呼び出します。イメージ ストリームがデコーダーに渡され、呼び出し元では必要に応じてファイル内のメタデータを扱うためのキャッシュ オプションを指定します。
enum WICDecodeOptions
{ WICDecodeMetadataCacheOnDemand,
WICDecodeMetadataCacheOnLoad }</code></pre>
アプリケーションの中には、他のアプリケーションよりも多くのメタデータを使用するものもあります。ほとんどのアプリケーションでは、イメージ ファイル内のすべてのメタデータにアクセスする必要はなく、必要に応じて特定のメタデータを要求します。ファイル ストリームを開いたままにしておいたり、メタデータへのアクセスが必要になるたびにディスク I/O を実行するのではなく、すべてのメタデータを前もってキャッシュに格納するアプリケーションもあります。呼び出し元でメタデータのキャッシュ オプションを指定しないと、既定のキャッシュ動作は要求時にキャッシュされることになります。つまり、アプリケーションからメタデータに対して特定の要求が行われないと、メタデータはメモリに読み込まれません。アプリケーションが WICDecodeMetadataCacheOnLoad を指定すると、メタデータが直ちにメモリに読み込まれ、キャッシュされます。メタデータが読み込み時にキャッシュされるときは、メタデータがキャッシュされた後にファイル ストリームを解放できます。
GetContainerFormat は、実装が簡単なメソッドです。デコーダーのインスタンスを作成するイメージのイメージ形式の GUID を返すだけです。このメソッドは IWICMetadataBlockReader および IWICBitmapEncoder にも実装されます。
GetDecoderInfo は、IWICBitmapDecoderInfo オブジェクトを返します。IWICBitmapDecoderInfo オブジェクトを取得するには、次に示すようにデコーダーの GUID を IWICComponentFactory インターフェイスの CreateComponentInfo メソッドに渡してから、IWICDecoderInfo インターフェイスを要求します。
IWICComponentInfo* piComponentInfo = NULL;
HRESULT hr;
hr = m_piComponentFactory->CreateComponentInfo(CLSID_This,&piComponentInfo);
hr = piComponentInfo->QueryInterface(IID_IWICBitmap DecoderInfo,
(void**)ppIDecoderInfo);</code></pre>
GetFrameCount は、単にコンテナー内のフレーム数を返します。複数のフレームをサポートするコンテナーもあれば、1 コンテナーにつき1 つのフレームのみをサポートするコンテナーもあります。
GetFrame は IWICBitmapDecoder インターフェイスでおそらく最も重要なメソッドです。フレームには実際のイメージ ビットが含まれていて、このメソッドから返されたフレーム デコーダー オブジェクトが、要求されたイメージの実際のデコードを行うためです。そしてこのフレーム デコーダー オブジェクトは、デコーダーの作成にあたり、実装が必要なもう 1 つのオブジェクトです。このインターフェイスの詳細については、IWICBitmapFrameDecode を参照してください。
GetPreview はイメージのプレビューを返します。プレビューの詳細については、IWICBitmapEncoder インターフェイスの SetPreview メソッドを参照してください。
イメージ形式に埋め込みの JPEG プレビューが含まれていても、イメージをデコードするために JPEG デコーダーを作成する必要はありません。実際には、作成しないことを強くお勧めします。代わりに、プレビューやサムネイルのデコード操作は、WIC プラットフォームに付属の JPEG デコーダーに委任します。これを行うには、ストリームでプレビュー イメージのデータの先頭を探し、ImagingFactory で CreateDecoderFromStream メソッドを呼び出します。
IWICBitmapDecoder* piPreviewDecoder = NULL;
IWICBitmapFrameDecode* piPreviewFrame = NULL;
IWICBitmapSource* piPreview = NULL;
HRESULT hr;
hr = m_piImagingFactory->CreateDecoderFromStream(m_piStream, NULL,
WICDecodeMetadataCacheOnDemand, &piPreviewDecoder);
hr = piPreviewDecoder->GetFrame(0, piPreviewFrame);
hr = piPreviewFrame->QueryInterface(IID_IWICBitmapSource,(void**)&piPreview);
ページのトップへ
2. IWICBitmapCodecProgressNotification
コーデックが、サイズの大きなイメージに対して CopyPixels や WritePixels などの I/O 操作を実行している場合、操作が完了するまでに数秒または数分もかかることがあります。エンド ユーザーがアプリケーションに不満を持つ最も多い原因の 1 つは、実行時間の長い操作を中断できないことです。このような場合、ユーザーはアプリケーションがハングしていると考えます。アプリケーションが反応しなくなったとき、ユーザーはコンピューターの制御を回復しようとして、多くの場合、アプリケーションを閉じるかコンピューターを再起動します。
この IWICBitmapCodecProgressNotification インターフェイスは、現在の操作の進行状況を呼び出し元に通知することができます。この場合、アプリケーションでは、コーデックから指定された間隔で呼び出しを実行できるコールバック関数を指定します。このコールバック関数を使用して進行状況を示す UI を表示し、ユーザーに操作状況を通知します。ユーザーが進行状況のダイアログ ボックスで [キャンセル] をクリックすると、アプリケーションはコールバック関数から WINCODEC_ERR_ABORTED を返します。この場合、コーデックでは指定された操作をキャンセルして、操作を実行していたメソッドの呼び出し元に、この HRESULT を返す必要があります。
このインターフェイスは、コンテナー レベルのデコーダー クラスに実装します。
interface IWICBitmapCodecProgressNotification : public IUnknown
{
HRESULT RegisterProgressNotification (
PFNProgressNotification pfnProgressNotification,
LPVOID pvData,
DWORD dwProgressFlags );
}
RegisterProgressNotification はアプリケーションから呼び出され、指定された間隔でコーデックから呼び出すことができるコールバック関数を登録します。1 つ目のパラメーター pfnProgressNotification は、コーデックが定期的に呼び出すコールバック関数へのポインターです。
pvData パラメーターは、コールバック関数が呼び出されたときに、コーデックからコールバック関数に必ず返す、呼び出し元のオブジェクトを指します。このオブジェクトにはどのようなオブジェクトでも指定できます。コーデックに対しては特別な意味を持ちません。
dwProgressFlags パラメーターは、コーデックからコールバック関数を呼び出すタイミングを指定します。このパラメーターには 2 つの列挙値があり、論理演算子の OR (|) で結合して指定できます。WICProgressOperation 列挙値では、デコード (WICProgressOperationCopyPixels)、エンコード (WICProgerssOperationWritePixels)、またはその両方 (WICProgressOperationAll) のうち、どの操作の実行中にコールバック関数を呼び出すかを指定します。
enum WICProgressOperation
{ WICProgressOperationCopyPixels,
WICProgerssOperationWritePixels,
WICProgressOperationAll };</code></pre>
コーデックでは、操作の開始から終了までの間定期的にコールバック関数を呼び出しますが、呼び出し元で特定の要件を指定することができます。WICProgressNotification 列挙値は、操作中のどの時点でコールバック関数を呼び出すかを示します。呼び出し元で WICProgressNotificationBegin が指定された場合は、操作の開始時 (0.0) にコールバック関数を呼び出す必要があります。呼び出し元で特定の要件を指定しない場合は、この指定を省略できます。同様に、呼び出し元で WICProgerssNotificationEnd が指定された場合は、操作の完了時 (1.0) にコールバック関数を呼び出す必要があります。呼び出し元が WICProgressNotificationAll を指定している場合は、開始時と終了時、および操作の開始から終了までの間定期的にコールバック関数を呼び出す必要があります。呼び出し元では WICProgerssNotificationFrequent を指定することもできます。このフラグは、高い頻度で (約 2 本のスキャンラインごとに) コールバックを求めることを示します (通常、呼び出し元はイメージのサイズが非常に大きい場合にしかこのフラグを使用しません)。それ以外の場合は、処理するスキャンラインの合計の 10% 以下の本数ごとにコールバックするのが適切です。
enum WICProgressNotification
{ WICProgressNotificationBegin,
WICProgerssNotificationEnd,
WICProgerssNotificationFrequent,
WICProgressNotificationAll };</code></pre>
指定したデコーダーまたはエンコーダーのインスタンスには、1 度に 1 つのコールバックしか登録できません。アプリケーションから RegisterProgressNotification が 2 回以上呼び出されると、以前に登録したコールバック関数が新しい関数に置き換えられます。コールバックの登録をキャンセルするには、呼び出し元で pfnProgressNotification パラメーターを NULL に設定します。
コールバック関数のシグネチャは次のとおりです。
typedef HRESULT (*PFNProgressNotification) ( LPVOID pvData,
ULONG uFrameNum,
WICProgressOperation operation,
double dblProgress );</code></pre>
コールバック関数を呼び出すときは pvData パラメーターを使用して、アプリケーションでコールバック関数の登録時に指定したのと同じ pvData を渡します。
uFrameNum パラメーターでは、処理中のフレームのインデックスを示します。
operation パラメーターは、デコード時は WICProgressOperationCopyPixels、エンコード時は WICProgressOperationWritePixels に設定します。
dblProgress パラメーターには、0.0 (操作の開始時点) ~ 1.0 (操作の完了時点) の範囲内の数値を指定します。この値は、処理するスキャンラインの合計本数に対する、既に処理済みのスキャンライン本数の比率を反映したものにします。
ページのトップへ
3. IWICBitmapSource
アプリケーションの観点では、IWICBitmapSource はイメージを扱う場合に非常に重要なインターフェイスです。このインターフェイスはイメージ ソースを高いレベルで抽象化して表したもので、IWICBitmapFrameDecode、IWICBitmap、およびすべての変換インターフェイス (IWICBitmapScaler、IWICBitmapClipper、IWICBitmapFlipRotator、IWICFormatConverter) など、イメージを表すすべての WIC インターフェイスがこのインターフェイスから派生します。どのようなときでも、メモリ内の実際のビットマップから IWICBitmapSource オブジェクトが返される場合と返されない場合があります。このため、アプリケーションによる処理効率が大幅に向上します。これは、イメージを抽象的に扱うことができ、アプリケーションでイメージの表示や印刷を行う準備ができるまで、メモリ リソースを消費することなく変換操作を変換パイプラインでつなぐことができるためです。アプリケーションの準備が整った時点で、最終的な変換で CopyPixels メソッドが呼び出され、選択した変換が適用されたイメージのメモリ内のビットマップが取得されます。
interface IWICBitmapSource : IUnknown
{
// 必須のメソッド
HRESULT GetSize ( UINT *puiWidth,
UINT *puiHeight );
HRESULT GetPixelFormat ( WICPixelFormatGUID *pPixelFormat );
HRESULT GetResolution ( double *pDpiX,
double *pDpiY );
HRESULT CopyPixels ( const WICRect *prc,
UINT cbStride,
UINT cbBufferSize,
BYTE *pbBuffer );
// 省略可能なメソッド
HRESULT CopyPalette ( IWICPalette *pIPalette );
}
コーデックの観点では、IWICBitmapSource メソッドがフレーム デコーダー オブジェクトに実装されるため、これらのメソッドについては IWICBitmapSource から派生した IWICBitmapFrameDecode の他のメソッドと併せて後ほど説明します。
ページのトップへ
4. IWICBitmapFrameDecode
IWICBitmapFrameDecode は、実際のイメージ ビットへのアクセスを提供するフレーム レベルのインターフェイスです。このインターフェイスは、フレーム レベルのデコード クラスに実装します。このインターフェイスは IWICBitmapSource から派生しているため、IWICBitmapFrameDecode の実装には IWICBitmapSource メソッドの実装が含まれます。IWICBitmapFrameDecode の他のメソッドは、フレーム レベルのサムネイル、イメージのカラー コンテキスト、およびフレームのメタデータ クエリ リーダーへのアクセスを提供します。
interface IWICBitmapFrameDecode : IWICBitmapSource
{
// 必須のメソッド
HRESULT GetThumbnail ( IWICBitmapSource **ppIThumbnail );
HRESULT GetColorContexts ( UINT cCount,
IWICColorContext **ppIColorContexts,
UINT *pcActualCount );
HRESULT GetMetadataQueryReader ( IWICMetadataQueryReader **ppIMetadataQueryReader );
// IWICBitmapSource から継承されるメソッド
HRESULT GetSize ( UINT *puiWidth,
UINT *puiHeight );
HRESULT GetPixelFormat ( WICPixelFormatGUID *pPixelFormat );
HRESULT GetResolution ( double *pDpiX,
double *pDpiY );
HRESULT CopyPixels ( const WICRect *prc,
UINT cbStride,
UINT cbBufferSize,
BYTE *pbBuffer );
// 省略可能なメソッド
HRESULT CopyPalette ( IWICPalette *pIPalette );
}
GetThumbnail は、現在のフレームのサムネイルを返します。パフォーマンス上の理由から、サムネイルは JPEG 形式でエンコードされるのが最も一般的です。デコーダーでのプレビューと同様に、サムネイルに独自の JPEG デコーダーを提供することは必須事項でも推奨事項でもありません。代わりに、WIC によって提供される JPEG デコーダーに委任することをお勧めします。
サムネイルの詳細については、WICBitmapFrameEncode インターフェイスの SetThumbnail メソッドを参照してください。
GetColorContexts は、このフレーム内のイメージに関連付けられた、有効なカラー コンテキスト (カラー プロファイルとも呼ばれます) を返します。ほとんどの場合、返されるカラー コンテキストは 1 つですが、2 つ、またはまれにそれ以上返される場合もあります。呼び出し元は、cCount パラメーターを設定してこのパラメーターに指定した数だけ IWICColorContext オブジェクトを渡します。このメソッドは、イメージに関連付けられたカラー プロファイルの実際のカラー コンテキスト データを、IWICColorContext オブジェクトに設定します。実際に返すことができる数より多くても、イメージに関連付けられたカラー コンテキストの実際の数を pcActualCount パラメーターに設定します (使用できるカラー コンテキストが、呼び出し元から渡された IWICColorContext オブジェクトの数よりも多い場合は、他に使用できるカラー コンテキストがあることを呼び出し元に通知します)。
GetMetadataQueryReader は、アプリケーションでイメージ フレームからメタデータを取得するために使用できる IWICMetadataQueryReader を返します。このインターフェイスはメタデータ ハンドラーによって実装されるため、特定のメタデータ形式に属する特定のメタデータ プロパティをアプリケーションから照会できます。メタデータ ハンドラーの詳細については、IWICMetadataBlockReader で説明します。
MetadataQueryReaderのインスタンスを作成するには、ComponentFactory で CreateQueryReaderFromBlockReader を呼び出します。
IWICMetadataQueryReader* piQueryReader = NULL;
HRESULT hr;
hr = m_piComponentFactory->CreateQueryReaderFromBlockReader(
static_cast<IWICMetadataBlockWriter*>(this),
&piQueryReader);</code></pre>
GetSize、GetPixelFormat、および GetResolution は、それぞれの名前が示すとおり、イメージの要求されたプロパティを返します。
CopyPixels は、IWICBitmapSource において最も興味深いメソッドです。これは、アプリケーションが表示またはプリンタに出力できるビットマップをメモリ内に作成する必要があるときに、呼び出すメソッドです。このメソッドは、イメージ ビットの実際のデコードを実行します。パラメーターには、メモリにコピーするソース イメージ内の領域を表す四角形、1 本のスキャンライン内のバイト数を指定するストライド、アプリケーションによって割り当てられたメモリのバッファー サイズ、および要求されたイメージ ビットのコピー先バッファーへのポインターを渡します (バッファー オーバーランによるセキュリティ ホールの発生を防ぐために、バッファーにコピーするイメージ データの量は、必ず cbBufferSize パラメーターで指定した量のみにしてください)。
CopyPalette は、インデックス付きピクセル形式を持つコーデックのみ、実装が必要です。イメージにインデックス付き形式を使用する場合に、このメソッドを使用してイメージに使用される色のパレットを返します。コーデックにインデックス付き形式が含まれない場合は、WINCODEC_ERR_PALETTEUNAVAILABLE を返します。
ページのトップへ
5. IWICMetadataBlockReader
イメージの中に複数のメタデータ ブロックが含まれていることがよくあります。このような場合、各メタデータ ブロックでは異なる種類の情報が異なる形式で公開されます。WIC モデルでは、メタデータ ハンドラーは、デコーダーと同様に、個別のコンポーネントで、実行時に検出できます。各メタデータ形式には個別のハンドラーがあり、各メタデータ ハンドラーは処理対象のメタデータ形式をサポートしているイメージ形式と共に使用できます。そのため、使用するイメージ形式が EXIF、XMP、IPTC などをサポートする場合、WIC に付属の形式には標準のメタデータ ハンドラーを利用できます。独自のメタデータ ハンドラーを作成する必要はありません。もちろん、新しいメタデータ形式を作成する場合は、その形式用のメタデータ ハンドラーを作成する必要があります。作成するメタデータ ハンドラーは標準のものと同様に実行時に検出され呼び出されますが、それについてはこのホワイト ペーパーでは説明しません。
注 イメージ形式が TIFF コンテナーまたは JPEG コンテナーを基盤にしている場合、新しいメタデータ形式または専用のメタデータ形式を開発しない限り、メタデータ ハンドラーを作成する必要はありません。TIFF コンテナーと JPEG コンテナーでは、メタデータ ブロックが IFD 内に配置され、各コンテナーの IFD 構造が異なります。WIC にはこれら両方のコンテナー形式の IFD ハンドラーが用意されています。これらの IFD ハンドラーは、IFD 構造を移動し、標準のメタデータ ハンドラーに委任してその中のメタデータにアクセスします。そのため、イメージ形式がこれらのコンテナーのいずれかを基盤にしていれば、自動的に WIC IFD ハンドラーを利用できます。ただし、独自に最上位レベルの独特なメタデータ構造を持つ専用のコンテナー形式を使用する場合、IFD ハンドラーと同様に、その最上位レベルの構造を移動して、適切なメタデータ ハンドラーに委任できるハンドラーを作成する必要があります。
WIC により、一貫性のある一連のインターフェイスによって、すべてのイメージ形式を同じ方法で処理できるようにする抽象層がアプリケーションに提供されるのと同様に、メタデータ形式に関する抽象層がコーデックの作成者に提供されます。上記のとおり、コーデックの作成者は通常、イメージに存在する可能性があるさまざまなメタデータ形式を直接処理する必要はありません。ただし、コーデックの作成者は必ずメタデータ ブロックを列挙する手段を提供する必要があり、そのために各ブロックに適切なメタデータ ハンドラーを検出してそのインスタンスを作成できるようになっています。これが IWICMetadataBlockReader インターフェイスの目的です。
このインターフェイスは、フレーム レベルのデコード クラスに実装する必要があります。また、イメージ形式が個々のイメージ フレームの外部にあるグローバル メタデータを公開する場合は、コンテナー レベルのデコーダー クラスにもこのインターフェイスを実装する必要があります。
interface IWICMetadataBlockReader : IUnknown
{
// すべてのメソッドが必須
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetCount ( UINT *pcCount );
HRESULT GetEnumerator ( IEnumUnknown **ppIEnumMetadata );
HRESULT GetReaderByIndex ( UINT nIndex,
IWICMetadataReader **ppIMetadataReader );
}
GetContainerFormat は IWICBitmapDecoder の GetContainerFormat メソッドと同じです。
GetCount はフレームに関連付けられた最上位レベルのメタデータ ブロックの数を返します。
GetEnumerator は、呼び出し元がフレーム内のメタデータ ブロックを列挙してそれらのメタデータを読み取るために使用できる列挙子を返します。このメソッドを実装するには、メタデータのブロックごとにメタデータ リーダーを作成し、メタデータ リーダーのコレクションを列挙する列挙オブジェクトを実装する必要があります。列挙オブジェクトは IEnumUnknown を実装する必要があるため、ppIEnumMetadata パラメーターに列挙オブジェクトを返すときに列挙オブジェクトを IEnumUnknown にキャストできます。
列挙オブジェクトを実装している場合、IWICMetadataBlockReader オブジェクトの初回作成時または列挙オブジェクトの初回作成時にすべてのメタデータ リーダーを作成するか、または手抜きをして IEnumUnknown::Next メソッドの実装の内部にメタデータ リーダーを作成することもできます。多くの場合、この手抜き方式でメタデータ リーダーを作成するのが効率的ですが、次の例では (領域を節約するためだけに) コンストラクターですべてのメタデータ リーダーを作成しています。
public class MetadataReaderEnumerator : public IEnumUnknown
{
UINT m_current;
UINT m_blockCount;
IWICMetadataReader** m_apiMetadataReader;
IStream* m_piStream;
MetadataReaderEnumerator()
{
// m_blockCount をフレーム内のメタデータ ブロックの数に
// 設定します。
...
m_apiMetadataReader = IWICMetadataReader*[m_blockCount];
m_current = 0;
for (UINT x=0; x < m_blockCount; x++)
{
// ファイル内のメタデータの x 番目のブロックが
// 存在する位置を検索し m_piStream を
// その位置にシークします。
...
m_piComponentFactory-> CreateMetadataReaderFromContainer(
GUID_ContainerFormatTiff, NULL,
WICPersistOptions.WICPersistOptionsDefault |
WICMetadataCreationOptions.WICMetadataCreationDefault,
m_piStream, &m_apiMetadataReader[x]);
}
}
// IEnumUnknown インターフェイスと IUnknown インターフェイスの実装
...
}
メタデータ リーダーを作成するには、IWICComponentFactory::CreateMetadataReaderFromContainer メソッドを使用します。このメソッドを呼び出すとき、guidContainerFormat パラメーターにコンテナー形式の GUID を渡します。メタデータ リーダーの製造元に優先順位がある場合、pGuidVendor パラメーターに優先する製造元の GUID を渡すことができます。たとえば、自社でメタデータ ハンドラーを作成していて、独自のメタデータ ハンドラーが存在するときにそのハンドラーを優先して使用する場合は、自社の GUID を渡すことができます。多くの場合は NULL を渡すだけになります。NULL を渡すと、システムが適切なメタデータ リーダーを選択します。特定の製造元を要求し、要求した製造元のメタデータ リーダーがコンピューターにインストールされている場合、WIC はその製造元のリーダーを返します。ただし、要求した製造元のメタデータ リーダーがコンピューターにインストールされていない場合で、利用可能な適切なメタデータ リーダーが存在する場合は、優先する製造元のものでなくても、そのリーダーを返します。ブロック内のメタデータの種類に適したメタデータ リーダーがコンピューターに存在しない場合は、コンポーネント ファクトリが UnknownMetadataHandler を返します。この場合、メタデータ ブロックは BLOB として処理され、ファイルのメタデータ ブロックは解析されることなくシリアル化解除されます。
dwOptions パラメーターには、適切な WICPersistOptions と適切な WICMetadataCreationOptionsを論理 OR 演算子で組み合わせて指定します。WICPersistOptions はコンテナーのレイアウトを指定します。既定値は LittleEndian です。
enum WICPersistOptions
{ WICPersistOptionDefault,
WICPersistOptionLittleEndian,
WICPersistOptionBigEndian,
WICPersistOptionStrictFormat,
WICPersistOptionNoCacheStream,
WICPersistOptionPreferUTF8 };</code></pre>
WICMetadataCreationOptions は、特定のブロックのメタデータ形式を読み取れるメタデータ リーダーがコンピューターに存在しない場合に UnknownMetadataHandler を返す必要があるかどうかを指定します。既定値は AllowUnknown で、UnknownMetadtataHandler の作成を常に許可します。UnknownMetadataHandler は認識されないメタデータを BLOB として処理します。認識されないメタデータは解析できませんが、BLOB としてストリームに書き込まれ、エンコード中にストリームにそのまま書き戻されて保持されます。このため、専用のメタデータ形式またはシステムに付属していないメタデータ形式用に、メタデータ ハンドラーを作成しておくことをお勧めします。コンピューターにメタデータを認識するハンドラーが存在しない場合でも、メタデータはそのままの状態で保持されるため、後で適切なメタデータ ハンドラーがインストールされたときに、このメタデータは存在していて、読み取ることができます。UnknownMetadataHandler の作成を許可しない場合、代わりに認識されないメタデータを破棄または上書きすることができます。これは、データ損失になります (専用のメタデータ用に独自のメタデータ ハンドラーを作成する場合は、このメタデータ ブロック自体の外部の項目への参照を含めてはならないことに注意してください。UnknownMetadataHandler がメタデータをそのままの状態で保持する場合でも、ファイル編集時にメタデータは移動されるため、各自のブロックの外部の項目への参照は無効になります)。
enum WICMetadataCreationOptions
{ WICMetadataCreationDefault,
WICMetadataCreationAllowUnknown,
WICMetadataCreationFailUnknown };</code></pre>
pIStream パラメーターはデコードする実際のストリームです。ストリームを渡す前に、リーダーを要求しているメタデータ ブロックの先頭にシークする必要があります。ppiReader パラメーターには、IStream の現在位置にあるメタデータ ブロックに適切なメタデータ リーダーが返されます。
GetReaderByIndex はコレクション内の要求されたインデックス位置にあるメタデータ リーダーを返します。
ページのトップへ
6. IWICBitmapSourceTransform
このインターフェイスは省略可能ですが、パフォーマンスが大幅に向上するので、すべてのデコーダーのフレーム レベルのデコード クラスにこのインターフェイスを実装することを強くお勧めします。コーデックがカメラの RAW コーデックである場合は、このインターフェイスの実装は必須です。カメラの RAW ファイル形式がこれに対応していない場合は、そのファイル形式の次回改訂時に、このインターフェイスのサポートを追加することを強くお勧めします。Windows 7 では、カメラの RAW コーデックはこれをサポートすることが必須になるためです。アプリケーションから特定の対象領域、サイズ、印刷の向き、ピクセル形式が要求された場合、完全な解像度でイメージ全体をデコードしてから要求された変換を適用するのではなく、WIC が IWICBitmapFrameDecode オブジェクトで IWICBitmapSourceTransform インターフェイスの QI (QueryInterface の呼び出し) を行います。
フレーム デコーダーがこのインターフェイスをサポートしている場合、WIC は適切なメソッドを呼び出し、フレーム デコーダーが要求された変換を実行できるかを判断するか、デコーダーにより要求されたものに最も近いサイズまたはピクセル形式を提供できるようにします。デコーダーが要求された変換を実行できる場合、WIC は適切なパラメーターを指定して IWICBitmapSourceTransform::CopyPixels を呼び出します。デコーダーが要求された変換の一部しか実行できない場合、WIC はデコーダーに実行可能な変換を実行するよう要求します。そのうえで、WIC は、WIC 変換オブジェクト (IWICBitmapScaler、IWICBitmapClipper、IWICBitmapFlipRotator、IWICFormatConverter) を使用して、IWICBitmapSourceTransform::CopyPixels の呼び出しの結果に対して、フレーム デコーダーが実行できなかった残りの変換を実行します。デコーダーが IWICBitmapSourceTransform をサポートしない場合、WIC は変換オブジェクトを使用してすべての変換を実行する必要があります。通常、イメージ全体をデコードしてから変換を実行するよりも、デコーダーでデコード処理中に変換を実行する方がはるかに効率的です。これは、非常に小さいサイズに縮小したり、ピクセル形式の変換を行うような操作には、特に当てはまります。
interface IWICBitmapSourceTransform : IUnknown
{
// 必須のメソッド
HRESULT DoesSupportTransform ( WICTransformOptions dstTransform,
BOOL *pfIsSupported);
HRESULT CopyPixels ( WICRect *prcSrc,
UINT uiWidth,
UINT uiHeight,
WICPixelFormatGUID * pguidDstFormat,
WICBitmapTransformOptions dstTransform,
UINT nStride,
UINT cbBufferSize,
BYTE *pbBuffer );
// 省略可能なメソッド
HRESULT GetClosestSize ( UINT *puiWidth,
UINT *puiHeight);
HRESULT GetClosestPixelFormat ( WICPixelFormatGUID *pguidDstFormat);
}
DoesSupportTransform は、デコーダーが要求された回転操作や反転操作をサポートしているかどうかを問い合わせます。要求される WICBitmapTransformOptions は次のとおりです。
enum WICBitmapTransformOptions
{ WICBitmapTransformRotate0,
WICBitmapTransformRotate90,
WICBitmapTransformRotate180,
WICBitmapTransformRotate270,
WICBitmapTransformFlipHorizontal,
WICBitmapTransformFlipVertical };</code></pre>
CopyPixels は IWICBitmapSource インターフェイスの CopyPixels メソッドと同様、イメージの実際のデコード作業を行うメソッドですが、IWICBitmapSourceTransform の CopyPixels メソッドの方がはるかに興味深く強力なメソッドで、イメージ処理パフォーマンスを大幅に向上させることができます。
複数の変換操作が要求された場合、その結果は操作の実行順序によって異なります。コーデック間での予測可能性と一貫性を確保するためには、すべてのコーデックが同じ順序で操作を実行することが重要です。以下の操作を実行する際の正規の順序は、次のとおりです。
- 拡大縮小
- トリミング
- 回転
ピクセル形式の変換は、他の変換に影響しないため、いつでも実行できます。
最初のパラメーター prcSrc はイメージをクリッピングする対象領域を指定するときに使用します。変換では、クリッピングの前に拡大縮小が実行されるので、イメージのクリッピングだけでなく拡大縮小も行う場合、対象領域はイメージを拡大縮小した後に決定します。
2 番目と 3 番目のパラメーターは、イメージの拡大縮小後のサイズを示します。
pguidDstFormat パラメーターはデコード後のイメージに要求されるピクセル形式を示します。WIC から既に GetClosestPixelFormat が呼び出されているので、これはデコーダーがサポート対象であることを示しているピクセル形式にする必要があります。
dstTransform パラメーターは、要求された回転角度や、イメージを上下左右のいずれかまたはすべての方向に反転するかどうかを示します。この場合も、WIC から既に DoesSupportTransform が呼び出されているため、要求される変換は、デコーダーがサポート対象であることを示している変換である必要があります。回転は、必ずサイズの拡大縮小とクリッピングの後で実行してください。
GetClosestSize は 2 つの入出力パラメーターを受け取ります。呼び出し元は puiWidth パラメーターと puiHeight パラメーターを使用して、呼び出し元が希望する理想的なイメージのデコード後のサイズを指定します。ただし、デコーダーはイメージを DCT サイズの倍数にしかデコードできません。イメージ形式が異なれば、DCT サイズも異なる場合があります。そのため、デコーダーは独自の DCT サイズに基づいて、要求されたサイズに最も近いサイズを特定し、戻り値として puiWidth と puiHeight に特定したサイズを設定します。元のサイズよりも大きいサイズが要求されても、コーデックでサイズの拡大をサポートしていない場合は、元のサイズを返します。
GetClosestPixelFormat は、要求されたピクセル形式に最も近く、かつデコーダーがデータを損失せずに提供できるピクセル形式を特定するために使用します。重要なのは、イメージのサイズが増えても、小さいピクセル形式よりも大きいピクセル形式に変換する方が常に有益であるということです。大きいピクセル形式に変換しておけば、必要に応じてより制限された形式に再変換することができますが、データが失われた場合、それを取り戻すことはできません。
ページのトップへ
7. IWICDevelopRaw
このインターフェイスは RAW イメージの処理に固有の処理オプションを公開します。RAW コーデックでは、必ず IWICDevelopRaw インターフェイスをサポートします。RAW コーデックの中には、このインターフェイスによって公開されているすべての設定をサポートしないものもありますが、作成するコーデックで実行可能なすべての設定をサポートする必要があります。どの RAW コーデックも、SetRotation メソッドと SetRenderQuality メソッドを実装する必要があります。このインターフェイスを実装する場合は、IWICDevelopRawNotificationCallback も実装してください。
また、他のコーデックでは省略可能でも、RAW コーデックでは実装が必須のメソッドとインターフェイスがあります。これには、コンテナー レベルのデコーダー クラスの GetPreview メソッドと GetThumbnail メソッドや、フレーム レベルのデコード クラスの IWICBitmapSourceTransform インターフェイスが含まれます。
WICDevelopRaw メソッドを使用して設定した設定は、他のメタデータを保持する方法と一貫した方法で、コーデックで保持しますが、元の "As Shot" 設定 (撮影時の設定) の上書きはしないでください。メタデータを保持し、LoadParameterSet と GetCurrentParameterSet を実装することで、RAW 処理アプリケーションが、処理設定を取得し、これをセッション全体に適用できるようになります。
IWICDevelopRaw インターフェイスの主な目的の 1 つは、アプリケーション開発者が、RAW パラメーターを調整するためのユーザー インターフェイスを構築できるようにすることです。このインターフェイスは、さまざまなコーデック間で可能な限り一貫した動作になるようにします。エンド ユーザーがパラメーターを調整する場合に、(wincodecs.idl/.h で指定されているように) パラメーターの最小範囲と最大範囲にマップされた最小値と最大値を、スライダー コントロールを使用して調整するとします。これをサポートするには、すべてのパラメーター範囲が線形に扱われるように、あらゆる努力をする必要があります。スライダー コントロールの感度が高すぎることがないように、各パラメーターにできるだけ広い範囲を設定することも必要です。少なくとも許容最大範囲の 50% に対応する必要があります。たとえば、コントラストの許容最大範囲が純色の灰色から純色の黒または白までの場合、既定値は 0.0 で、コーデックでサポートする最小範囲は、既定値と最小値 (-1.0) である純色の灰色の少なくとも半分から、既定値と最大値 (+1.0) である純色の黒または白の少なくとも半分までになります。
interface IWICDevelopRaw : IWICBitmapFrameDecode
{
HRESULT QueryRawCapabilitiesInfo ( WICRawCapabilitiesInfo *pInfo );
HRESULT LoadParameterSet ( WICRawParameterSet ParameterSet );
HRESULT GetCurrentParameterSet ( IPropertyBag2 **ppCurrentParameterSet );
HRESULT SetExposureCompensation ( double ev );
HRESULT GetExposureCompensation ( double *pEV );
HRESULT SetWhitePointRGB ( UINT Red, UINT Green, UINT Blue );
HRESULT GetWhitePointRGB ( UINT *pRed, UINT *pGreen, UINT *pBlue );
HRESULT SetNamedWhitePoint ( WICNamedWhitePoint WhitePoint );
HRESULT GetNamedWhitePoint ( WICNamedWhitePoint *pWhitePoint );
HRESULT SetWhitePointKelvin ( UINT WhitePointKelvin );
HRESULT GetWhitePointKelvin ( UINT *pWhitePointKelvin );
HRESULT GetKelvinRangeInfo ( UINT *pMinKelvinTemp,
UINT *pMaxKelvinTemp,
UINT *pKelvinTempStepValue );
HRESULT SetContrast ( double Contrast );
HRESULT GetContrast ( double *pContrast );
HRESULT SetGamma ( double Gamma );
HRESULT GetGamma ( double *pGamma );
HRESULT SetSharpness ( double Sharpness );
HRESULT GetSharpness ( double *pSharpness );
HRESULT SetSaturation ( double Saturation );
HRESULT GetSaturation ( double *pSaturation );
HRESULT SetTint ( double Tint );
HRESULT GetTint ( double *pTint );
HRESULT SetNoiseReduction ( double NoiseReduction );
HRESULT GetNoiseReduction ( double *pNoiseReduction );
HRESULT SetDestinationColorContext (const IWICColorContext *pColorContext );
HRESULT SetToneCurve ( UINT cbToneCurveSize,
const WICRawToneCurve *pToneCurve );
HRESULT GetToneCurve ( UINT cbToneCurveBufferSize,
WICRawToneCurve *pToneCurve,
UINT *pcbActualToneCurveBufferSize );
HRESULT SetRotation ( double Rotation );
HRESULT GetRotation ( double *pRotation );
HRESULT SetRenderQuality ( WICRawRenderQuality RenderQuality );
HRESULT GetRenderQuality ( WICRawRenderQuality *pRenderQuality );
HRESULT SetNotificationCallback ( IWICDevelopRawNotificationCallback *pCallback );
}
QueryRawCapabilitiesInfo は、この RAW ファイルに対してサポートされている一連の機能を返します。IWICRawCapabilitiesInfo 構造体は次のように定義します。
struct WICRawCapabilitiesInfo
{
UINT cbSize;
UINT CodecMajorVersion;
UINT CodecMinorVersion;
WICRawCapabilities ExposureCompensationSupport;
WICRawCapabilities ContrastSupport;
WICRawCapabilities RGBWhitePointSupport;
WICRawCapabilities NamedWhitePointSupport;
UINT NamedWhitePointSupportMask;
WICRawCapabilities KelvinWhitePointSupport;
WICRawCapabilities GammaSupport;
WICRawCapabilities TintSupport;
WICRawCapabilities SaturationSupport;
WICRawCapabilities SharpnessSupport;
WICRawCapabilities NoiseReductionSupport;
WICRawCapabilities DestinationColorProfileSupport;
WICRawCapabilities ToneCurveSupport;
WICRawRotationCapabilities RotationSupport;
}
この構造体で使用される WICRawCapabilities 列挙値は、次のように定義します。
enum WICRawCapabilities
{ WICRawCapabilityNotSupported,
WICRawCapabilityGetSupported,
WICRawCapabilityFullySupported };</code></pre>
最後のフィールドは、WICRawRotationCapabilities 列挙値で、次のように定義します。
enum WICRawRotationCapabilities
{ WICRawRotationCapabilityNotSupported,
WICRawRotationCapabilityGetSupported,
WICRawRotationCapabilityNinetyDegreesSupported
WICRawRotationCapabilityFullySupported };</code></pre>
LoadParameterSet では、ユーザーが As Shot 設定を使用するかどうか、ユーザーによって調整された設定を使用するかどうか、イメージを自動修正するためにデコーダーを要求するかどうかなどを指定できます。
enum WICRawParameterSet
{ WICAsShotParameterSet,
WICUserAdjustedParameterSet,
WICAutoAdjustedParameterSet };</code></pre>
GetCurrentParameterSet は現在のパラメーター設定を含む IPropertyBag2 を返します。その後、呼び出し元は、このパラメーター設定をエンコーダー オプションとしてエンコーダーに渡すことができます。
Set/GetExposureCompensation は、最終的な出力に適用する露出補正を示します。EV の有効範囲は -5.0 ~ +5.0 です。
Set/GetWhitePointRGB、Set/GetNamedWhitePoint、Set/GetWhitePointKelvin、および GetKelvinRangeInfo はいずれも、ホワイト ポイントを RGB 値、事前に設定された名前付きの値、またはケルビン値のいずれかで取得および設定する手段を提供します。ケルビン値の許容範囲は 1,500 ~ 30,000 です。Get/SetNamedWhitePoint は、次の列挙値を使用します。
enum WICNamedWhitePoint
{
WICWhitePointDefault,
WICWhitePointDaylight,
WICWhitePointCloudy,
WICWhitePointShade,
WICWhitePointTungsten,
WICWhitePointFluorescent,
WICWhitePointFlash,
WICWhitePointUnderwater,
WICWhitePointCustom, // ホワイト バランスで画像 (グレー カード) を使用する場合
WICWhitePointAutoWhiteBalance,
WICWhitePointAsShot
};
SetContrast/GetContrast は出力に適用するコントラストの程度を示します。コントラストを指定する際の有効範囲は -1.0 ~ +1.0 で、既定値は 0.0 です。
Set/GetGamma は、適用するガンマ値を示します。ガンマ値の有効範囲は 0.2 ~ 5.0 で、既定値は 1.0 です。通常、ガンマは伝統的なガンマのべき乗関数 (ユニティ ゲインを指定した線形のべき乗関数) を使用して実装されます。輝度はガンマ値の増加に伴って増加し、ガンマ値がゼロに近づくにつれて減少します (ただし、伝統的なガンマ値の計算では 0 を指定すると 0 除算エラーが発生するので、最小値を 0 にはできません。論理最小極限値は [1/最大値] です。したがって、最小値は 0.2 になります)。
Set/GetSharpness は適用するシャープの程度を示します。有効範囲は -1.0 ~ +1.0 で、既定値は 0.0 です。-1.0 を指定すると、まったくシャープが適用されません。
Set/GetSaturation は適用する鮮やかさの程度を示します。鮮やかさの有効範囲は -1.0 ~ +1.0 です。通常の鮮やかさにする場合は 0.0、鮮やかさをまったく適用しない場合は -1.0、最大限の鮮やかさを表す場合は +1.0 を指定します。
Set/GetTint は、緑/マゼンタ軸を基に適用する濃淡を示します。有効範囲は -1.0 ~ +1.0 で、スケールの負の値が緑色で、正の値がマゼンタです。0.0 は濃淡の変更をしないことを示します。濃淡のスケールは、色温度に直交するように定義されます。
Set/GetNoiseReduction は適用するノイズ リダクションの程度を示します。有効範囲は -1.0 ~ +1.0 で、既定値 0.0 です。ノイズ リダクションを行わない場合は -1.0、ノイズ リダクションを最大限に適用する場合は +1.0 を指定します。
SetDestinationColorContext は、イメージに適用するカラー プロファイルを指定します。現在のカラー プロファイルを取得するには、IWICBitmapFrameDecode::GetColorContext を呼び出します。
Set/GetToneCurve は適用する色調曲線を指定します。各点の間は線形補間を想定しています。pToneCurve は WICRawToneCurve 構造体で、WICRawToneCurvePoint 構造体の配列と、その配列内の点の数を保持します。
struct WICRawToneCurve
{
UINT cPoints;
WICRawToneCurvePoint aPoints[];
}
WICRawToneCurvePoint は入力値と出力値を保持します。
struct WICRawToneCurvePoint
{
double Input;
double Output;
}
呼び出し元から pToneCurve パラメーターに NULL を渡す場合、WICRawToneCurve に対して必要なサイズを pcbActualToneCurveBufferSize パラメーターに渡します。
Set/GetRotation は適用する回転角度を示します。回転の値に 90.0 を指定すると、右回りに 90 度回転します (IWICDevelopRaw::SetRotation を使用する場合と、IWICBitmapSourceTransform::CopyPixels メソッドを使用して回転を設定する場合の違いは、IWICDevelopRaw::SetRotation を使用して設定した回転角度はコーデックで保持されますが、IWICBitmapSourceTransform::CopyPixels を使用して回転を設定した場合は、イメージがメモリ内で回転されるだけです)。
Set/GetRenderQuality は、呼び出し元が必要とする出力の品質レベルを示します。ユーザーがパラメーターを調整する際、アプリケーションでは変更が適用された場合に実際のイメージがおおよそどのように見えるのかをすばやく表示できる必要があります。このため、イメージは通常、実際のイメージの解像度ではなく、画面の解像度以下で表示されます。最も重要なことは、ユーザーにすばやくフィードバックを提供することです。この場合はアプリケーションがドラフト モードの品質を要求しているため、非常に高速に行われる必要があります。ユーザーがすべての変更を終え、変更をドラフト モードでプレビュー表示し、現在の設定を適用して完全にイメージをデコードする段階で、アプリケーションは最高品質デコードを要求します。通常、印刷の際にもこのような対応が求められます。速度と品質の間で適宜トレードオフが必要な場合、アプリケーションは標準品質を要求します。
enum WICRawRenderQuality
{ WICRawRenderQualityDraftMode,
WICRawRenderQualityNormalQuality ,
WICRawRenderQualityBestQuality };</code></pre>
SetNotificationCallback は、RAW 処理パラメーターのいずれかが変更されたときに呼び出されるデコーダー用に、アプリケーションによって作成されたコールバック関数を登録します。IWICDevelopRawNotificationCallback のシグネチャには Notify というメソッドが 1 つだけ含まれています。Notify はパラメーターを 1 つ受け取ります。そのパラメーターは、RAW 処理パラメーターのうち、どのパラメーターが変更されたかを示すマスクです。
HRESULT Notify ( UINT NotificationMask );
OR 演算子を使用して組み合わせて NotificationMask に指定できる値を次に示します。
WICRawChangeNotification_ExposureCompensation
WICRawChangeNotification_NamedWhitePoint
WICRawChangeNotification_KelvinWhitePoint
WICRawChangeNotification_RGBWhitePoint
WICRawChangeNotification_Contrast
WICRawChangeNotification_Gamma
WICRawChangeNotification_Sharpness
WICRawChangeNotification_Saturation
WICRawChangeNotification_Tint
WICRawChangeNotification_NoiseReduction
WICRawChangeNotification_DestinationColorContext
WICRawChangeNotification_ToneCurve
WICRawChangeNotification_Rotation
WICRawChangeNotification_RenderMode
ページのトップへ
4. WIC 対応エンコーダーの実装
WIC デコーダーの実装と同様に、WIC エンコーダーを実装するには 2 つのクラスを作成する必要があります。これらのクラスのインターフェイスは、「Windows Imaging Component のしくみ」の「エンコード」に記載したエンコーダーの機能に直接対応します。
これらのクラスの 1 つでは、コンテナー レベルのサービスを提供し、コンテナー内の個々のイメージ フレームのシリアル化を管理します。このクラスは IWICBitmapEncoder インターフェイスを実装します。イメージ形式がコンテナー レベルのメタデータをサポートする場合、このクラスに IWICMetadataBlockWriter インターフェイスも実装する必要があります。
もう 1 つのクラスではフレーム レベルのサービスを提供し、コンテナー内の各フレームのイメージ ビットを実際にエンコードします。また、各クラスのメタデータ ブロックを反復処理し、適切なメタデータ ライターを要求してブロックをシリアル化します。このクラスでは、IWICBitmapFrameEncode インターフェイスと IWICMetadataBlockWriter インターフェイスを実装します。このクラスには IStream メンバーを含む必要があります。IStream メンバーは、コンテナー レベルのクラスによりインスタンスの作成時に初期化され、Commit メソッドによってフレーム データがシリアル化されます。
RAW 形式など、アプリケーションがその RAW 形式へのエンコードまたは再エンコードを実行できるようにする必要があるとは限らない場合があります。これは、RAW ファイルの目的が、カメラから取得されたとおりのセンサー データを保持することにあるためです。ただし、エンコードを有効にしない場合でも、メタデータを追加できるように、基本エンコーダーは実装する必要があります。この場合、エンコーダーはメタデータの書き込みに必要なメソッドをサポートするだけでよいため、デコーダーから取得されたイメージ ビットをそのままコピーできます。
a. エンコーダー インターフェイス
次の表に WIC エンコーダーによって実装されるインターフェイスを示します。また、この後のクラス図では、継承階層を示します。
インターフェイス |
機能 |
実装 |
IWICBitmapEncoder |
コンテナー レベルのサービス |
必須 |
IWICBitmapCodecProgressNotification |
進行状況の通知とキャンセルのサポート |
推奨 |
IWICMetadataBlockWriter |
メタデータのシリアル化サービス |
省略可能 (コンテナー レベルのメタデータをサポートする形式のみ必須) |
インターフェイス |
機能 |
実装 |
IWICBitmapFrameEncode |
フレーム レベルのサービス |
必須 |
IWICMetadataBlockWriter |
メタデータのシリアル化サービス |
必須 |
エンコーダー インターフェイスがデコーダー インターフェイスとほぼ同じ構成であること、およびこれらのインターフェイスのメソッドの大半が関連するデコーダー インターフェイスのメソッドに対応していることがわかります。WIC 対応デコーダーの実装について既に説明したので、WIC 対応エンコーダーの実装については簡単に理解できると思います。
- IWICBitmapEncoder
- IWICBitmapProgressNotification
- IWICBitmapFrameEncode
- IWICMetadataBlockWriter
ページのトップへ
1. IWICBitmapEncoder
これは、IWICBitmapDecoder インターフェイスに相当するインターフェイスで、イメージ ファイルをエンコードする際に最初に使用されます。IWICBitmapDecoder がイメージ コンテナーからコンテナー レベルのプロパティと個々のフレームの取得に使用されるように、IWICBitmapEncoder はコンテナー レベルのプロパティを設定して個々のイメージ フレームをコンテナーにシリアル化するために使用されます。このインターフェイスは、コンテナー レベルのエンコーダー クラスに実装します。
interface IWICBitmapEncoder : public IUnknown
{
// 必須のメソッド
HRESULT Initialize ( IStream *pIStream,
WICBitmapEncoderCacheOption cacheOption );
HRESULT GetContainerFormat ( GUID *pguidContainerFormat );
HRESULT GetEncoderInfo ( IWICBitmapEncoderInfo **pIEncoderInfo );
HRESULT CreateNewFrame ( IWICBitmapFrameEncode **ppIFrameEncode,
IPropertyBag2 **ppIEncoderOptions );
HRESULT Commit ( void );
// 省略可能なメソッド
HRESULT SetPreview ( IWICBitmapSource *pIPreview );
HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
HRESULT SetColorContexts ( UINT cCount,
IWICColorContext **ppIColorContext );
HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter
**ppIMetadataQueryWriter );
HRESULT SetPalette ( IWICPalette *pIPalette);
};
イメージ形式の中にはグローバルなサムネイル、カラー コンテキスト、メタデータが含まれているものもありますが、多くのイメージ形式ではこれらをフレーム単位で提供するだけだということを、デコーダーのところで説明しました。したがって、これらを設定するメソッドは、IWICBitmapEncoder では省略可能ですが、IWICBitmapFrameEncode では必須です。IWICBitmapEncoder の省略可能なメソッドについては、IWICBitmapFrameEncode で説明します。IWICBitmapFrameEncode は、これらのメソッドを実装することが最も多いインターフェイスです。
グローバル サムネイルをサポートしない場合は、IWICBitmapEncoder の SetThumbnail メソッドから WINCODEC_ERR_CODECNOTHUMBNAIL を返します。コンテナー レベルのパレットをサポートしない場合、またはエンコードするイメージにインデックス付き形式が含まれない場合は、SetPalette メソッドから WINCODEC_ERR_PALETTEUNAVAILABLE を返します。その他のサポートしていないメソッドについては、WINCODEC_ERR_UNSUPPORTEDOPERATION を返します。
Initialize は、IWICBitmapEncoder のインスタンスの作成後に、このオブジェクトで最初に呼び出されるメソッドです。イメージ ストリームがエンコーダーに渡され、呼び出し元は必要に応じてキャッシュ オプションを指定します。デコーダーの場合、ストリームは読み取り専用ですが、エンコーダーに渡すストリームは書き込み可能です。エンコーダーは、すべてのイメージ データとメタデータをこのストリームにシリアル化します。また、エンコーダーのキャッシュ オプションもデコーダーとは異なります。
enum WICBitmapEncoderCacheOption
{ WICBitmapEncoderCacheInMemory,
WICBitmapEncoderCacheTempFile,
WICBitmapEncoderNoCache };</code></pre>
アプリケーションは、メモリにイメージ データをキャッシュする、一時ファイルにイメージ データをキャッシュする、またはイメージ データをキャッシュせずにディスク ファイルに直接書き込むよう、エンコーダーに要求できます。一時ファイルにイメージ データをキャッシュするよう要求すると、エンコーダーはディスクに一時ファイルを作成し、メモリにキャッシュせずにそのファイルに直接データを書き込みます。呼び出し元がキャッシュ オプションを指定しない場合は、各フレームを順番どおりにコミットしないと、その次のフレームを作成できません。
GetContainerFormat は IWICBitmapDecoder の GetContainerFormat メソッドと同様の方法で実装します。
GetEncoderInfo は IWICBitmapEncoderInfo オブジェクトを返します。IWICBitmapEncoderInfo オブジェクトを取得するには、エンコーダーの GUID を IWICComponentFactory インターフェイスの CreateComponentInfo メソッドに渡してから、IWICEncoderInfo インターフェイスを要求します。
IWICBitmapDecoder::GetDecoderInfo のサンプル コードを参照してください。
CreateNewFrame は IWICBitmapDecoder の GetFrame に相当するエンコーダーのメソッドです。このメソッドは IWICBitmapFrameEncode オブジェクトを返します。このオブジェクトは、コンテナー内の任意のフレームのイメージ データを実際にシリアル化するオブジェクトです。
WIC のメリットの 1 つは、すべてのイメージ形式を同じ方法で処理できるようにする抽象層をアプリケーションに提供することです。しかし、すべてのイメージ形式がまったく同じというわけではありません。イメージ形式の中には他のイメージにはない機能が備わっているものがあります。アプリケーションでそのような一意の機能を使用できるようにするには、コーデックでそれらの機能を公開する手段を提供することが必要です。これがエンコーダー オプションの目的です。コーデックでなんらかのエンコーダー オプションをサポートする場合、サポートするエンコーダー オプションを公開する IPropertyBag2 オブジェクトを作成して、このメソッドの ppIEncoderOptions パラメーターに作成したオブジェクトを返します。これにより、呼び出し元がこの IPropertyBag2 オブジェクトを使用して、コーデックがサポートするエンコーダー オプションを特定できます。呼び出し元でサポートされているエンコーダー オプションのいずれかに値を指定する必要がある場合、IPropertyBag2 オブジェクトの関連プロパティに値を割り当て、Initialize メソッドで新規作成する IWICBitmapFrameEncode オブジェクトにその値を渡します。
IPropertyBag2 オブジェクトのインスタンスを作成するには、まず PROPBAG2 構造体を作成してから、エンコーダーがサポートする各エンコーダー オプションと各プロパティのデータ型を指定する必要があります。次に、書き込み時に各プロパティの値範囲を適用し、競合する値や重複する値があれば調整する、IPropertyBag2 オブジェクトを実装する必要があります。単純な、競合のないエンコーダー オプションのセットの場合は、IWICComponentFactory::CreateEncoderPropertyBag メソッドを呼び出すことができます。これにより、PROPBAG2 構造体に指定したプロパティを使用して単純な IPropertyBag2 オブジェクトが作成されます。ただし、この場合も、値範囲を適用する必要があります。高度なエンコーダー オプションの場合や、競合する値を調整する必要がある場合は、独自の IPropertyBag2 実装を作成することになります。
UINT cuiPropertyCount = 0;
IPropertyBag2* piPropertyBag = NULL;
PROPBAG2* pPropBagOptions;
HRESULT hr;
// エンコーダーがサポートするオプションを使用して
// piPoropertyBag を初期化し、公開するエンコーダー
// オプションのプロパティの数で cuiPropertyCount を
// 初期化するコードをここに挿入します。
...
hr = piComponentFactory->CreateEncoderPropertyBag(
pPropBagOptions, cuiPropertyCount, &piPropertyBag );</code></pre>
WIC は、一般的なイメージ形式の一部が使用する正規のエンコーダー オプションをいくつか提供しています。正規のエンコーダー オプションはすべて省略可能で、コーデックはこれらのオプションを必ずしもサポートする必要はありません。これらのオプションを正規オプションとして提供している理由は、これらのオプションをサポートする形式でイメージ ファイルを保存するときに、ユーザーがこれらのオプションを指定できるようにする UI を公開しているアプリケーションが多くあるためです。これらのオプションを指定する正規の手段を提供することで、一貫した方法でアプリケーションがエンコーダーにオプションを渡しやすくしています。以下の表に、正規のエンコーダー オプションを示します。
エンコーダー オプション |
VARTYPE |
値の範囲 |
Lossless |
VT_BOOL |
True/False |
ImageQuality |
VT_R4 |
0 ~ 1.0 |
CompressionQuality |
VT_R4 |
0 ~ 1.0 |
BitmapTransform |
VT_UI1 |
WICBitmapTransformOptions |
コーデックが無損失エンコードをサポートする場合は、アプリケーションがイメージを無損失エンコードするように要求する手段として、Lossless エンコーダー オプションをコーデックで公開します呼び出し元がこのプロパティを True に設定している場合は、ImageQuality オプションを無視して、イメージを無損失エンコードします。
ImageQuality オプションを使用すると、アプリケーションでイメージをエンコードする際に、どの程度忠実にエンコードするかを指定できます。このオプションを使用することで、ユーザーはイメージの品質を優先するか速度やファイル サイズを優先するかを指定できます。JPEG は、このような指定が可能なイメージ形式の 1 つです。値 0.0 の場合、忠実さは重要視されず、エンコーダーは損失の度合いが最も高いアルゴリズムを使用します。値 1.0 の場合は、忠実さが最も重要で、エンコーダーはできる限り忠実にエンコードを実行します (コーデックによっては、これは Lossless オプションと同義になることがあります。ただし、コーデックが無損失エンコードをサポートしている場合や、Lossless オプションが True に設定されている場合は、ImageQuality オプションは無視されます)。
CompressionQuality オプションを使用すると、イメージのエンコード時に使用する圧縮効率をアプリケーションが指定できます。非常に効率的なアルゴリズムを使用すると、比較的効率的ではない圧縮アルゴリズムと同じ品質でありながら、よりサイズの小さいイメージ ファイルを生成できる場合がありますが、エンコードに時間がかかる可能性があります。このオプションを使用すると、同レベルの品質を維持しながら、ユーザーがファイル サイズを優先するか、エンコード速度を優先するかを指定できます。TIFF は、このような指定が可能なイメージ形式の 1 つです (JPEG などの形式ではさまざまなレベルの圧縮をサポートしていますが、圧縮率を高くするほどイメージの品質が低下します。したがって、JPEG コーデックでは CompressionQuality オプションではなく ImageQuality オプションを公開します)。このオプションの値が 0.0 の場合は、ファイル サイズは大きくなりますが、忠実さを損なわずに、イメージをできる限り高速に圧縮します。値が 1.0 の場合は、エンコードに時間がかかるとしても、同レベルの品質で、できる限りサイズが小さいファイルを作成します。コーデックによっては ImageQuality オプションと CompressionQuality オプションの両方をサポートしています。両方がサポートされる場合、ImageQuality オプションでは許容できる損失の度合いを指定し、CompressionQuality オプションでは指定した品質レベルを保ちつつ、サイズと速度のどちらを優先するかを指定します。
BitmapTransform オプションを使用すると、呼び出し元がエンコード時に回転角度または上下左右の向きの反転を指定できます。要求する変換の指定に使用する WICBitmapTransformOptions 列挙値は、IWICBitmapSourceTransform インターフェイスでデコード時の変換の要求に使用するのと同じ列挙値です。
エンコーダーのオプションは、正規のエンコーダー オプションだけではないことに注意してください。エンコーダー オプションの目的は、エンコーダーがその機能を公開できるようにすることで、公開できる機能の種類に制限はありません。エンコーダー オプションについては、詳細なドキュメントを用意してください。アプリケーションがこのメソッドから返すプロパティ バッグを使用して、サポートされているオプションの名前、型、値範囲を検出できるとしても、その意味や、そのオプションを UI でどのように公開するかを調べるには、ドキュメントを参照する以外に方法はありません。
Commit はすべてのイメージ データとメタデータをストリームにシリアル化した後で呼び出すメソッドです。このメソッドを使用して、プレビュー イメージのデータをストリームにシリアル化します。また、必要に応じてグローバルなサムネイル、メタデータ、パレットなどもシリアル化します。ファイル ストリームは、ストリームを開いたアプリケーションにより閉じられるため、このメソッドではファイル ストリームを閉じません。
IWICBitmapFrameEncode:Commit メソッドの説明で、IWICBitmapEncoderCacheOptions がこのメソッドの動作にどのように影響するかを詳しく説明しています。
SetPreview はイメージのプレビューを作成するために使用します。厳密にはすべてのイメージにプレビューが必要なわけではありませんが、プレビューを作成することを強くお勧めします。現在のデジタル カメラやスキャナでは非常に高い解像度のイメージが生成されます。このため、生成されるイメージはサイズが非常に大きくなる傾向があるので、デコードの処理に時間がかかります。次世代カメラのイメージのサイズはさらに大きくなるでしょう。優れたユーザー エクスペリエンスを提供するため、通常は JPEG 形式などのサイズが小さく解像度が低いイメージを提供することをお勧めします。これにより、ユーザーから要求があったときに "即座に" デコードして表示できます。アプリケーションではデコード対象の実際のイメージを要求する前にプレビューを要求できるので、ユーザーには優れたエクスペリエンスを提供できます。少なくとも、実際のイメージのデコードを待機中にイメージを画面サイズで表示できます。すべてのコーデックでプレビューを提供することをお勧めしますが、IWICBitmapSourceTransform をサポートしないコーデックでは必ずプレビューをサポートしてください。
JPEG プレビューを提供する場合、プレビューをエンコードするために JPEG エンコーダーを作成する必要はありません。プレビューとサムネイルのどちらをエンコードする場合も、WIC プラットフォームに付属の JPEG エンコーダーに操作を委任します。
ページのトップへ
2. IWICBitmapProgressNotification
IWICBitmapProgressNotification インターフェイスは省略可能ですが、コンテナー レベルのエンコーダー クラスに実装することをお勧めします。このインターフェイスはこのホワイト ペーパーのデコーダーのところで詳しく説明しています。実装方法は、デコーダーでもエンコーダーでも同じです。
3. IWICBitmapFrameEncode
これは、IWICBitmapFrameDecode インターフェイスに相当するインターフェイスです。このインターフェイスは、各フレームのイメージ ビットの実際のエンコードを行うフレーム レベルのエンコード クラスに実装します。
interface IWICBitmapFrameEncode : public IUnknown
{
// 必須のメソッド
HRESULT Initialize ( IPropertyBag2 *pIEncoderOptions );
HRESULT SetSize ( UINT width,
UINT height );
HRESULT SetResolution ( double dpiX,
double dpiY );
HRESULT SetPixelFormat (WICPixelFormatGUID *pPixelFormat);
HRESULT SetColorContexts ( UINT cCount,
IWICColorContext **ppIColorContext );
HRESULT GetMetadataQueryWriter ( IWICMetadataQueryWriter
**ppIMetadataQueryWriter );
HRESULT SetThumbnail ( IWICBitmapSource *pIThumbnail );
HRESULT WritePixels ( UINT lineCount,
UINT cbStride,
UINT cbBufferSize,
BYTE *pbPixels );
HRESULT WriteSource ( IWICBitmapSource *pIWICBitmapSource,
WICRect *prc );
HRESULT Commit ( void );
// 省略可能なメソッド
HRESULT SetPalette ( IWICPalette *pIPalette );
};
Initialize は、IWICBitmapFrameEncode オブジェクトのインスタンスの作成後に、このオブジェクトで最初に呼び出されるメソッドです。このパラメーターはエンコーダーのオプションを表し、コンテナー レベルのデコーダーの CreateNewFrame メソッドで作成し、そのメソッドの pIEncoderOptions パラメーターで呼び出し元に返したものと同じ IPropertyBag2 インスタンスです。CreateNewFrame では、フレーム レベルのエンコーダーでサポートされるエンコードのオプションを表すプロパティを IPropertyBag2 構造体に設定しました。呼び出し元は既に必要なエンコード オプションのパラメーターを示すプロパティの値を提供しているので、ここでは IWICBitmapFrameEncode オブジェクトを初期化するために、CreateNewFrame メソッドから返されたオブジェクトを渡します。指定されたオプションは、イメージ ビットのエンコード時に適用します。
SetSize および SetResolution は、名前が示すとおりの処理を行います。呼び出し元はこれらのメソッドを使用して、エンコードするイメージのサイズと解像度を指定します。
SetPixelFormat は、イメージをエンコードするピクセル形式を要求するために使用します。要求されたピクセル形式をサポートしていない場合は、サポートしている最も近いピクセル形式の GUID を入出力パラメーターである pPixelFormat に返します。
SetColorContexts は、作業対象のイメージに 1 つ以上の有効なカラー コンテキスト (カラー プロファイルとも呼ばれます) を指定するために使用します。カラー コンテキストの指定は重要で、後からイメージをデコードするアプリケーションは、これにより元のカラー プロファイルを、イメージの表示または印刷に使用するデバイスの目的のカラー プロファイルに変換できます。カラー プロファイルがないと、異なるデバイス間で同じ色を表現できません。これは、エンド ユーザーにとって大きな不満の種であり、モニタが異なると表示した写真の見た目が異なったり、画面で見る色と印刷結果の色が異なったりします。
GetMetadataQueryWriter は、イメージ フレームのメタデータ ブロック内に特定のメタデータ プロパティを挿入または編集するために、アプリケーションが使用できる IWICMetadataQueryWriter を返します。
IWICComponentFactory から IWICMetadataQueryWriter のインスタンスを作成する方法は 2、3 あります。IWICBitmapFrameDecode インターフェイスの GetMetadataQueryReader メソッドで、IWICMetadataBlockReader から IWICMetadataQueryReader を作成したときと同様に、独自の IWICMetadataBlockWriterからインスタンスを作成できます。
IWICMetadataQueryWriter* piMetadataQueryWriter = NULL;
HRESULT hr;
hr = m_piComponentFactory->CreateQueryWriterFromBlockWriter(
static_cast<IWICMetadataBlockWriter*>(this), &piMetadataQueryWriter);</code></pre>
または、前述のメソッドを使用して取得したものと同様に、既存の IWICMetadataQueryReader からインスタンスを作成することもできます。
hr = m_piComponentFactory->CreateQueryWriterFromReader(
piMetadataQueryReader, pguidVendor, &piMetadataQueryWriter);</code></pre>
pguidVendor パラメーターを使用すると、メタデータ ライターのインスタンスを作成するときに使用する QueryWriter に特定の製造元を指定できます。たとえば、独自のメタデータ ライターを提供する場合は、独自の製造元 GUID を指定できます。このパラメーターは省略可能で、特に優先する指定がなければ NULL を渡すことができます。
SetThumbnail は、サムネイルを提供するために使用します。どのイメージも、グローバル サムネイル、各フレームのサムネイル、またはその両方のサムネイルを提供する必要があります。GetThumbnail メソッドと SetThumbnail メソッドは、コンテナー レベルでは省略可能ですが、コーデックで IWICBitmapDecoder の GetThumbnail メソッドから WINCODEC_ERR_CODECNOTHUMBNAIL を返す場合は、WIC はフレーム 0 に対しては IWICBitmapFrameDecode で GetThumbnail メソッドを呼び出します。どちらにもサムネイルがない場合、WIC はイメージ全体をデコードし、それをサムネイルのサイズに縮小する必要があります。これは、サイズの大きいイメージではパフォーマンスの大幅な低下につながる可能性があります。
サムネイルは、すばやくデコードおよび表示できるサイズと解像度にします。このため、サムネイルには JPEG イメージが最も多く使用されています。サムネイルに JPEG を使用する場合は、サムネイルをエンコードするために JPEG エンコーダーを、デコードするために JPEG デコーダーを作成する必要はありません。サムネイルをエンコードする場合もデコードする場合も、常に WIC プラットフォームに付属の JPEG コーデックに操作を委任します。
WritePixels は、エンコードのためにメモリ内のビットマップからスキャンラインに渡すために使用するメソッドです。このメソッドは、すべてのスキャンラインに渡されるまで繰り返し呼び出されます。lineCount パラメーターは、この呼び出しで書き込まれるスキャンラインの数を示します。cbStride パラメーターは、1 スキャンラインあたりのバイト数を示します。cbBufferSize パラメーターは、エンコードされる実際のイメージ ビットを含むバッファーで、pbPixels パラメーターに渡されるバッファーのサイズを示します。繰り返し実行された呼び出しの結果を合計したスキャンラインの高さが SetSize メソッドで指定された高さを超える場合は、WINCODEC_ERR_TOOMANYSCANLINES を返します。
WICBitmapEncoderCacheOption が WICBitmapEncoderCacheInMemory の場合、すべてスキャンラインに渡されるまで、スキャンラインをメモリにキャッシュします。エンコーダーのキャッシュ オプションが WICBitmapEncoderCacheTempFile の場合は、オブジェクトの初期化時に作成される一時ファイルにスキャンラインをキャッシュします。いずれの場合も、呼び出し元が Commit を呼び出すまでイメージはエンコードしません。キャッシュ オプションが WICBitmapEncoderNoCache の場合、可能であれば、エンコーダーはスキャンラインの受け取りと並行してスキャンラインをエンコードします (形式によってはこの操作は実行できないため、Commit が呼び出されるまでスキャンラインをキャッシュする必要があります)。
ほとんどの RAW コーデックでは、RAW ファイルでのイメージ ビットの変更をサポートしないため、WritePixels を実装しません。ただし、メタデータが追加されるとファイルのサイズが増え、ディスク上のファイルを書き換える必要が発生する可能性があるので、RAW コーデックでも WriteSource を実装します。その場合、既存のイメージ ビットをコピーできるようにする必要があり、WriteSource メソッドはこの操作を処理します。
WriteSource は、IWICBitmapSource オブジェクトをエンコードするために使用します。1 つ目のパラメーターは、IWICBitmapSource オブジェクトへのポインタです。2 つ目のパラメーターは、エンコードの対象領域を指定する WICRect です。このメソッドは、各四角形の幅がエンコードする最終イメージの幅と同じである限り、連続して複数回呼び出すことができます。prc パラメーターに渡された四角形の幅が、SetSize メソッドで指定された幅と異なる場合は、WINCODEC_ERR_SOURCERECTDOESNOTMATCHDIMENSIONS を返します。繰り返し実行された呼び出しの結果を合計したスキャンラインの高さが SetSize メソッドで指定された高さを超える場合は、WINCODEC_ERR_TOOMANYSCANLINES を返します。
このメソッドのキャッシュ オプションの動作は、前述の WritePixels メソッドと同じです。
Commit は、エンコードされたイメージ ビットをファイル ストリームにシリアル化するメソッドです。フレームのすべてのメタデータ ライターを反復処理して、ストリームにメタデータをシリアル化するようメタデータ ライターに要求します。エンコーダーのキャッシュ オプションが WICBitmapEncoderCacheInMemory または WICBitmapEncoderCacheTempFile の場合、このメソッドはイメージのエンコードも行います。キャッシュ オプションが WICBitmapEncoderCacheTempFile の場合、Commit メソッドはエンコード前にイメージ データのキャッシュに使用された一時ファイルの削除も実行します。
このメソッドは、WritePixels メソッドまたは WriteSource メソッドを使用して、イメージを構成するすべてのスキャンラインまたは四角形が渡された後に必ず呼び出します。WritePixels または WriteSource を繰り返し呼び出した結果得られた最終四角形のサイズは、SetSize メソッドで指定したサイズと同じになる必要があります。想定するサイズと一致しない場合、このメソッドは WINCODECERROR_UNEXPECTEDSIZE を返します。
メタデータ ライターを反復処理して、各メタデータ ライターにそのメタデータをストリームにシリアル化するよう指示するには、GetWriterByIndex を呼び出して各ブロックのライターの反復処理を行い、各メタデータ ライターで IWICPersistStream.Save を呼び出します。
IWICMetadataWriter* piMetadataWRiter = NULL;
IWICPersistStream* piPersistStream = NULL;
HRESULT hr;
for (UINT x=0; x < m_blockCount; x++)
{
hr = GetWriterByIndex(x, & piMetadataWriter);
hr = piMetadataWriter->QueryInterface(
IID_IWICPersistStream,(void**)&piPersistStream);
hr = piPersistStream->Save(m_piStream,
WICPersistOptions.WicPersistOptionDefault, true);
...
}
SetPalette は、インデックス付きの形式を持つコーデックのみに実装する必要があるメソッドです。イメージにインデックス付き形式を使用する場合に、このメソッドを使用してイメージに使用される色のパレットを指定します。コーデックにインデックス付き形式が含まれない場合は、このメソッドから WINCODEC_ERR_PALETTEUNAVAILABLE を返します。
ページのトップへ
4. IWICMetadataBlockWriter
フレーム レベルのエンコード クラスはこのインターフェイスを実装することで、すべてのメタデータ ブロックを公開して各ブロックに適したメタデータ ライターを要求します。イメージ形式がグローバル メタデータをサポートしている場合、個々のフレーム外で、コンテナー レベルのエンコーダー クラスにこのインターフェイスを実装することをお勧めします。メタデータ ハンドラーの詳細については、「WIC 対応デコーダーの実装」の IWICMetadataBlockReader の説明を参照してください。
interface IWICMetadataBlockWriter : IWICMetadataBlockReader
{
// すべてのメソッドが必須
HRESULT InitializeFromBlockReader ( IWICMetadataBlockReader *pIMDBlockReader );
HRESULT GetWriterByIndex ( UINT nIndex,
IWICMetadataWriter **ppIMetadataWriter );
HRESULT AddWriter (IWICMetadataWriter *pIMetadataWriter );
HRESULT SetWriterByIndex ( UINT nIndex,
IWICMetadataWriter *pIMetadataWriter );
HRESULT RemoveWriterByIndex ( UINT nIndex );
}
InitializeFromBlockReader は IWICMetadataBlockReader を使用してブロック ライターを初期化します。IWICMetadataBlockReader は、イメージをデコードしたデコーダーから取得できます。
UINT blockCount = 0;
IWICMetadataReader* piMetadataReader = NULL;
IWICMetadataWriter** apiMetadataWriter = NULL;
HRESULT hr;
hr = m_piBlockReader->GetCount(&blockCount);
apiMetadataWriter = IWICMetadataWriter*[blockCount];
for (UINT x=0; x < blockCount; x++)
{
hr = m_piBlockReader->GetReaderByIndex(&piMetadataReader);
hr = m_piComponentFactory->CreateMetadataWriterFromReader(
piMetadataReader, NULL, &apiMetadataWriter[x]);
}
IWICMetadataBlockReader を使用して IWICMetadataBlockWriter を初期化すると、IWICMetadataBlockReader オブジェクトによって公開されるメタデータ リーダーごとにメタデータ ライターのインスタンスが作成されます。したがって、アプリケーションがメタデータのブロックごとにライターを明示的に要求する必要はありません。
GetWriterByIndex は、n 個目のメタデータ ブロックの IWICMetadataWriter オブジェクトを返します。n は nIndex パラメーターに渡す値です。n 個目のブロック内のメタデータの種類を処理できるメタデータ ライターが登録されていない場合、コンポーネント ファクトリが UnknownMetadataHandler を返します。その結果、メタデータ ブロックは BLOB として処理されます。メタデータ ブロックは解析されることなく、ビット ストリームとしてシリアル化されます。
AddWriter を使用すると、呼び出し元で新しいメタデータ ライターを追加できます。アプリケーションがどの既存のメタデータ ブロックとも異なる形式のメタデータを追加する必要がある場合、このメソッドが必要です。たとえば、アプリケーションが XMP メタデータを追加する必要があるとします。既存の XMP メタデータ ブロックがない場合、アプリケーションは XMP メタデータ ライターのインスタンスを作成し、AddWriter メソッドを使用してメタデータ ライターのコレクションにこのインスタンスを追加する必要があります。
SetWriterByIndex は、コレクション内の特定のインデックス位置にメタデータ ライターを追加するために使用します。メタデータ ライターがそのインデックス位置に現存する場合、新しいメタデータ ライターに置き換えられます。
RemoveWriterByIndex は、コレクションからメタデータ ライターを削除するために使用します。
ページのトップへ
5. コーデックのインストールと登録
コーデックをインストールするときに、コーデックをレジストリに登録する必要があります。また、自社の形式のイメージがコンピューターに既に存在している場合に備えて、縮小表示キャッシュが必ず更新されるようにします。
ここでは、コーデックを登録して検出の対象にするために書き込みが必要なすべてのレジストリ キーについて説明します。また、コーデックがメタデータ検索の対象になるようにするエントリ、および Windows Vista のフォト ビューアーとエクスプローラの機能を更新するエントリについても説明します。さらに、コンピューターに既に存在する自社のイメージ形式のイメージの縮小表示キャッシュを更新するために、コーデックのインストーラーから呼び出す必要のある API についても説明します。最後に、コンピューターに自社のイメージ形式のイメージがある場合、ユーザーが簡単にそのコーデックを見つけてインストールできるようにする方法を説明します。
a. コーデックの登録
コーデックを登録する場合、実際の処理としては 2 つのコンポーネント (エンコーダーとデコーダー) を登録します。また、レジストリ エントリを作成し、自社のイメージ形式がサポートするメタデータ形式のメタデータ ハンドラーを使用して、コンテナー形式を登録する必要もあります。
1. 全般的なレジストリ エントリ
次のレジストリ エントリは、デコーダー用にもエンコーダー用にも作成する必要があります。
HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID},Author = "作成者名"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},Description = "コーデックの説明"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},DeviceManufacturer = "カメラの製造元"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},DeviceModels = "デバイス,デバイス"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},FriendlyName = "コーデックの名前"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},FileExtensions = ".abc, .xyz"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},Date = "mm-dd-yyyy"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},Vendor = {製造元 GUID}
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},ContainerFormat = {コンテナー形式 GUID}
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},Version = "メジャー.マイナー.ビルド.番号"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},SpecVersion = "メジャー.マイナー.ビルド.番号"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},MimeTypes = "イメージ/サンプル,イメージ/サンプル"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},SupportAnimation = 0 または 1
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},SupportChromakey = 0 または 1
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},SupportLossless = 0 または 1
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},SupportMultiframe = 0 または 1
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},Formats{ピクセル形式 GUID}
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},InProcServer32(Default) = "ドライブ:\パス\yourdll.dll"
HKEY_CLASSES_ROOT\CLSID{Encoder/Decoder CLSID},InProcServer32\ThreadingModel = "Apartment"|"Both"
注 Windows 7 のコーデックでは、ThreadingModel は "Both" にする必要があります。詳細については、「WIC でのマルチスレッド アパートメントのサポート」を参照してください。
FriendlyName、VendorGUID、ContainerFormat、MimeTypes、FileExtensions、および Formats の各エントリは必須です。その他はすべて省略可能です。
これらのエントリのほとんどは名前からどのようなものであるかわかりますが、いくつかのエントリについてはある程度説明が必要です。DeviceManufacturer と DeviceModels は RAW コーデック固有のエントリで、コーデックを適用できるカメラの製造元とカメラのモデルを示します。SpecVersion は、コーデックが準拠するイメージ形式の仕様のバージョンです。Formats エントリでは、コーデックがサポートするピクセル形式を指定します。1 つのコーデックで、複数のピクセル形式をサポートしている場合があります。その場合は、HKEY_CLASSES_ROOT\CLSID\{Encoder/Decoder CLSID}\Formats に複数のキーを入力します。
ページのトップへ
2. エンコーダー固有のレジストリ エントリ
上記の一覧にあるエンコーダーのエントリのほかに、検出エンジンがエンコーダーを見つけられるように、WIC Encoders 以下にもエンコーダーを登録する必要があります。登録するには、次のレジストリ エントリを作成します。次のエントリの 1 つ目の GUID は、WICBitmapEncoders の CATID です。
HKEY_CLASSES_ROOT\CLSID\{AC757296-3522-4E11-9862-C17BE5A1767E}\Instance\
{Encoder CLSID},CLSID = {Encoder CLSID}
HKEY_CLASSES_ROOT\CLSID{AC757296-3522-4E11-9862-C17BE5A1767E}\Instance\
{Encoder CLSID},Friendly Name = "エンコーダーの名前"</code></pre>
自社のコーデック用の新しいコンテナー形式を作成する場合は、イメージ内のメタデータ ブロックのメタデータ ライターをサポートするためのレジストリ エントリも作成する必要があります。次のエントリは、自社のコンテナー形式でサポートする各メタデータ形式用のメタデータ ライターの CLSID 以下に作成する必要があります。コーデックが TIFF コンテナーを使用する場合は、この情報は既にレジストリに登録されているため、次のエントリを作成する必要はありません。
HKEY_CLASSES_ROOT\CLSID\{Metadata Writer CLSID}\Containers\
{Container Format GUID},WritePosition =
コンテナーへの相対オフセット
HKEY_CLASSES_ROOT\CLSID{Metadata Writer CLSID}\Containers\
{Container Format GUID},WriteHeader =
メタデータ ヘッダーに使用するパターン
HKEY_CLASSES_ROOT\CLSID{Metadata Writer CLSID}\Containers\
{Container Format GUID},WriteOffset =
ヘッダーの先頭からのオフセット</code></pre>
TIFF または JPEG スタイルのコンテナー形式を使用する場合は、コンテナーとそのコンテナー形式間の関連付けを登録する必要があります。詳細については、「Windows プロパティ ストアとの統合」を参照してください。
ページのトップへ
3. デコーダー固有のレジストリ エントリ
すべてのエンコーダーとデコーダーに必要なレジストリ エントリのほかに、デコーダー固有のエントリとして、次のレジストリ エントリが必要です。
これらのエントリによって、WIC Decoders 以下にデコーダーが登録されます。次のエントリの 1 つ目の GUID は、WICBitmapDecoders の CATID です。
HKEY_CLASSES_ROOT\CLSID\{7ED96837-96F0-4812-B211-F13C24117ED3}\Instance\
{Decoder CLSID},CLSID = {Decoder CLSID}
HKEY_CLASSES_ROOT\CLSID{7ED96837-96F0-4812-B211-F13C24117ED3}\Instance\
{Decoder CLSID},Friendly Name = "デコーダーの名前"</code></pre>
「検出と判別」で説明したように、イメージ ファイルに埋め込まれた識別パターンを、デコーダーのレジストリ エントリで指定されたパターンと一致させることで、特定のイメージに適したデコーダーが実行時に検出されるようにしています。実行時にデコーダーが検出されるようにするには、次のようにイメージ形式に対して一意な識別パターンを登録する必要があります。次のレジストリ エントリは、EndOfStream エントリを除いてすべて必須です。EndOfStream エントリは省略可能で、これについてはこのコードの後で説明します。
HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns\0,Position =
ブロック内のオフセット
HKEY_CLASSES_ROOT\CLSID{Decoder CLSID}\Patterns\0,Length =
パターンの長さ
HKEY_CLASSES_ROOT\CLSID{Decoder CLSID}\Patterns\0,Pattern =
照合するパターン
HKEY_CLASSES_ROOT\CLSID{Decoder CLSID}\Patterns\0,Mask = FF FF FF FF
HKEY_CLASSES_ROOT\CLSID{Decoder CLSID}\Patterns\0,EndOfStream= 0 | 1
Position 値では、ファイル内の照合パターンまでのオフセットを指定します。
Length 値では、パターンの長さを宣言します。
Pattern 値では、パターンを構成する実際のビット列を指定します。このビット列を使用して、検出中にイメージ ファイル内の識別パターンと一致するかどうかが確認されます。
Mask 値を使用すると、パターン内にワイルドカード値を使用できます。マスクは、パターンとマスクに論理 AND 演算を実行することで適用されます。パターン内のビットで、値 0 のマスク ビットに対応するビットはすべて無視されます。
EndOfStream 値 (指定する場合) は、識別パターンのオフセットを、ストリームの先頭ではなく末尾から計算するかどうかを示します。イメージ形式の中には、識別パターンがファイルの末尾付近に置かれているものがあります。既定では先頭から検出を行うので、パターンがファイル末尾近くにある場合を除いて、このエントリは省略できます。
1 つのコーデックで、複数の識別パターンをサポートしている場合があります。その場合、HKEY_CLASSES_ROOT\CLSID\{Decoder CLSID}\Patterns 以下にすべてのキーを繰り返し入力し、数値キー (上記例の 0) を使用して異なるパターンを区別します。各パターンのキーには、4 つの値をそれぞれ含める必要があります。
自社のコーデック用の新しいコンテナー形式を作成する場合は、メタデータ ライターと同様に、イメージ内のメタデータ ブロックのメタデータ リーダーの検出をサポートするためのレジストリ エントリも作成する必要があります。次のエントリは、自社のコンテナー形式がサポートする各メタデータ形式用のメタデータ リーダーの CLSID 以下に作成する必要があります (コーデックが TIFF コンテナーを使用する場合は、この情報は既にレジストリに登録されています)。
HKEY_CLASSES_ROOT\CLSID\{Metadata Reader CLSID}\Containers\
{Container Format GUID}\0,Position =
コンテナーへの相対オフセット
HKEY_CLASSES_ROOT\CLSID{Metadata Reader CLSID}\Containers\
{Container Format GUID}\0,Pattern = メタデータ ヘッダーに使用するパターン
HKEY_CLASSES_ROOT\CLSID{Metadata Reader CLSID}\Containers\
{Container Format GUID}\0,Mask = FF FF FF FF
HKEY_CLASSES_ROOT\CLSID{Metadata Reader CLSID}\Containers\
{Container Format GUID}\0,DataOffset =
ヘッダーの先頭からのオフセット</code></pre>
メタデータ リーダーのエントリは検出にも使用されるため、デコーダーのエントリと非常に似ています。これらのエントリは、IWICMetadataBlockReader の実装によってメタデータ リーダーが要求されたときにコンポーネント ファクトリによって使用されます。コンポーネント ファクトリは、これらを使用してコンテナーでサポートされているメタデータ リーダーを見つけて、適切なメタデータ リーダーを選択します。
Position 値は、メタデータ ブロックのコンテナー内で照合するメタデータ ヘッダーまでのオフセットを示します。最上位のメタデータ ブロックの場合、この値はファイル ストリーム内のオフセットになります。他のメタデータ ブロックに入れ子になっているメタデータ ブロックの場合、この値は外側のメタデータ ブロックへの相対オフセットになります。
メタデータ ヘッダーの Pattern は、通常メタデータ ハンドラーによって定義されるので、パターンにとってコンテナー内に異なる形式を保持しなければならない十分な理由がない限り、各リーダーには標準のメタデータ ヘッダーを使用します。
DataOffset は省略可能で、実際のデータの開始点であるメタデータ ヘッダーの先頭からのオフセットを示します。メタデータがヘッダーからの特定のオフセット位置にない場合は、このエントリを省略できます。
ページのトップへ
4. Windows フォト ビューアーおよびエクスプローラとの統合
Windows フォト ビューアーとエクスプローラでサムネイルを表示し、標準のイメージ メタデータを検索および更新できるようにするには、コーデックにそのイメージ メタデータに関連付けられた IThumbnailProvider インターフェイスおよび IPropertyStore インターフェイスを実装する必要があります。IThumbnailProvider インターフェイスはサムネイルの取得および縮小表示キャッシュの作成に使用し、IPropertyStore インターフェイスはファイルに関連付けられたメタデータの検索および更新に使用します。Windows Vista のすべての種類のファイルにサムネイルとメタデータがありますが、ファイルの種類ごとに、ファイルのサムネイルとメタデータを取得または生成するためのこれらのインターフェイスを異なる方法で実装する必要があります。Windows Vista は、これらのインターフェイスの既定の実装を提供しています。IThumbnailProvider の既定の実装は、WIC 対応のすべてのイメージ形式に使用できます。IPropertyStore の既定の実装は、TIFF コンテナーまたは JPEG コンテナーを基盤とする WIC 対応のすべてのイメージ形式に使用できます。この両方のインターフェイスの既定の実装には、レジストリ エントリをいくつか追加するだけでイメージ形式を関連付けられます。
次のエントリは、Windows フォト ギャラリーおよびエクスプローラに対して、ファイル拡張子 (.ext) とその MIME の種類がイメージ形式に関連付けられていることを示します。
HKEY_CLASSES_ROOT \.ext,ContentType = イメージ形式の MIME の種類
HKEY_CLASSES_ROOT .ext,PerceivedType = "image"
同じメタデータ プロパティが、多くの場合異なるプロパティ名を使用して、複数のメタデータ スキーマで公開されていることがあります。このようなプロパティの 1 つが更新されても、他のプロパティが更新されなければ、ファイル内のメタデータの整合性が失われる可能性があります。Windows フォト プロパティ ハンドラーは、イメージの既定の IPropertyStore 実装を提供します。アプリケーションでも Windows フォト ギャラリーとエクスプローラでも、イメージ内のすべてのメタデータが常に同じ状態であるように、またアプリケーションが表示するプロパティと Windows フォト ギャラリーやエクスプローラで表示されるプロパティの整合性を確保するために、このプロパティ ハンドラーが使用されます。フォト プロパティ ハンドラーがメタデータを更新すると、これらのプロパティはファイル内に存在する共通メタデータ形式のすべてで一貫して更新されます。
フォト プロパティ ハンドラーがその役割を果たすには、コンテナー形式と、コンテナー形式に含まれるさまざまなプロパティを見つける手段を把握しておく必要があります。通常、フォト プロパティ ハンドラーでは、さまざまなメタデータ ブロックが専用のコンテナー形式にどのように配置されているかを把握することはできません。しかし、コンテナー形式に含まれているメタデータが TIFF コンテナー形式または JPEG コンテナー形式のいずれかのメタデータと同様に配置されている場合、フォト プロパティ ハンドラーはその情報を利用してメタデータをコンテナー形式で一貫して更新できます。
この関連付けを登録するには、次のレジストリ エントリを作成します。このエントリは、この GUID によって識別されるコンテナー形式が GUID 163bcc30-e2e9-4f0b-961d-a3e9fdb788a3 のコンテナー形式と同じメタデータ クエリ言語パスを認識することをフォト プロパティ ハンドラーに通知します (163bcc30-e2e9-4f0b-961d-a3e9fdb788a3 は TIFF コンテナー形式の GUID です)。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
PhotoPropertyHandler\ContainerAssociations,{Container Format GUID} =
{163bcc30-e2e9-4f0b-961d-a3e9fdb788a3}</code></pre>
次のエントリはフォト プロパティ ハンドラーの既定の実装 IPropertyStore を拡張子 ".ext" のファイルに関連付けます。1 つ目の GUID は IPropertyStore インターフェイスの IID で、2 番目はフォト プロパティ ハンドラーの IpropertyStore 実装の GUID です。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\
PropertySystem\PropertyHandlers\.ext,(Default) =
"{a38b883c-1682-497e-97b0-0a3a9e801682}"</code></pre>
TIFF コンテナー形式または JPEG コンテナー形式と互換性のない専用の形式を使用するコーデックでは、独自の IPropertyStore 実装を作成する必要があります。
Windows フォト ビューアーは WIC を基盤としているため、コーデックがインストールされている WIC 対応のイメージ形式はすべて表示できます。あるイメージ形式が Windows フォト ビューアーで開けることを Windows に通知するには、そのイメージ形式とのファイルの関連付けを作成する必要があります。それには、次のレジストリ エントリを作成します。
HKEY_CLASSES_ROOT\.ext,(Default) = ProgID (e.g.extfile)
HKEY_CLASSES_ROOT.ext\OpenWithProgids,ProgID
HKEY_CLASSES_ROOT.ext \OpenWithList\PhotoViewer.dll
HKEY_CLASSES_ROOT.ext\ShellEx\ContextMenuHandlers\
ShellImagePreview,(Default) =
"{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
HKEY_CLASSES_ROOT\SystemFileAssociations.ext
\OpenWithList\PhotoViewer.dll
HKEY_CLASSES_ROOT\SystemFileAssociations.ext\ShellEx\
ContextMenuHandlers\ ShellImagePreview,(Default) =
"{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
HKEY_CLASSES_ROOT\Image Format ProgID,(Default) = イメージ形式の名前
HKEY_CLASSES_ROOT\Image Format ProgID \DefaultIcon,(Default) =
ファイルの種類のアイコンへのパス,アイコン インデックス
HKEY_CLASSES_ROOT\Image Format ProgID\shell\open\command,(Default) =
"%SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll",
ImageView_Fullscreen %1"
HKEY_CLASSES_ROOT\Image Format ProgID\shell\open,MuiVerb =
"@%PROGRAM_FILES%\Windows Photo Gallery\photoviewer.dll,-3043"
HKEY_CLASSES_ROOT\Image Format ProgID\shell\open\DropTarget,Clsid =
"{FFE2A43C-56B9-4bf5-9A79-CC6D4285608A}"
HKEY_CLASSES_ROOT\Image Format ProgID\shell\printto\command,(Default) =
"%SystemRoot%\System32\rundll32.exe "%ProgramFiles%\Windows Photo Gallery\PhotoViewer.dll",
ImageView_PrintTo /pt "%1" "%2" "%3" "%4"</code></pre>
ProgID は、通常、ファイル拡張子に "file" という語を付加したものです (たとえば、ファイル拡張子が .abc の場合、ProgID は "abcfile" になります)。
ファイルの関連付けのために作成する必要がある標準のレジストリ エントリは他にもありますが、WIC や Windows Vista® に固有のものではないため、このホワイト ペーパーでは取り上げません。ファイルの関連付けに関する情報については、Windows SDK ドキュメントを参照してください。
次の 2 つのエントリは、標準の WIC サムネイル プロバイダーの実装を使用して、指定された拡張子を持つファイルのサムネイルを取得できることを示します。1 つ目の GUID は IThumbnailProvider インターフェイスの IID で、2 番目は Windows Vista の標準の IThumbnailProvider 実装の GUID です (HLCR\.ext\ShellEx\ 以下のすべてのエントリは、 HKCR\SystemFileAssociations\.ext\ShellEx\ 以下にも入力します)。
HKEY_CLASSES_ROOT \.ext\ShellEx\
{e357fccd-a995-4576-b01f-234630154e96},(Default) =
"{C7657C4A-9F68-40fa-A4DF-96BC08EB3551}"
HKEY_CLASSES_ROOT\SystemFileAssociations.ext\ ShellEx\
{e357fccd-a995-4576-b01f-234630154e96},(Default) =
"{C7657C4A-9F68-40fa-A4DF-96BC08EB3551}"</code></pre>
ページのトップへ
b. コーデック インストール時の縮小表示キャッシュの更新
コーデックをインストールする際、インストーラーはレジストリ エントリを書き込んだ後で、次の Windows API を呼び出す必要があります。
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL)
この呼び出しにより、新しいファイルの関連付け情報があることを Windows に通知します。自社のイメージ形式のイメージがコンピューターに既に存在する場合、縮小表示キャッシュにはそのイメージの既定のサムネイルが保持されます。これは、イメージを最初に取得した時点では、サムネイルを抽出できるデコーダーがなかったためです。新しいファイルの関連付けがあることを Windows に通知すると、縮小表示キャッシュは空のサムネイルを破棄し、デコードが可能になったファイルの実際のサムネイルを抽出します。
ページのトップへ
c. WIC 対応コーデックのユーザーへの提供
カメラの製造元の場合は、カメラに RAW コーデックを付属して提供できます。また、各社の Web サイトのダウンロード ページでコーデックを提供することもできます。ただし、ユーザーが、ある形式のイメージ ファイルを、たとえば友人や仕事関係者、または他の Web サイトから入手した場合、そのファイルのデコードに使用するコーデックを入手できる場所を知っているとは限りません。
この問題を緩和するために、Windows Vista (以降) では、ユーザーが目的のイメージ形式のコーデックを簡単に見つけてコンピューターにダウンロードできる手段を提供しています。Windows Vista フォト ギャラリーがあるファイル拡張子をイメージ形式であると認識し、その形式のコーデックがインストールされていない場合、写真を表示できないことをユーザーに知らせるダイアログ ボックスが表示されます。また、そのダイアログ ボックスでは、写真を表示するために必要なソフトウェアをダウンロードするかどうかが確認されます。ユーザーがダウンロードを承諾すると、コーデックの製造元のダウンロード サイトへのリンクがある、マイクロソフトが運営する Web サイトに移動します (または、ユーザーをダウンロード サイトに直接移動するよう依頼することもできます)。
あるイメージ形式のファイル拡張子が Windows Vista フォト ギャラリーで認識されるようにし、ユーザーがダウンロード サイトに直接移動できるようにするには、次の操作を行う必要があります。
- 目的のコーデックのダウンロード サイトを用意します (提供するコーデックごとに個別のページを用意しても、すべてのコーデックのダウンロードを掲載した単一のページを用意してもかまいません)。ダウンロード サイトをローカライズします。また、カメラのモデルを基に、簡単に検索できるようにします。
- マイクロソフトに目的のイメージ形式の拡張子と、ダウンロード サイトの URL の一覧を提供します。 また、将来開発された新しいコーデックの拡張子やダウンロード サイトの URL への変更をマイクロソフトに通知し、新しい情報がフォト ギャラリーに追加されるようにする必要があります。
ページのトップへ
6. まとめ
Windows Imaging Component (WIC) プラットフォームでコーデックを構築すると、WIC を基盤とするすべてのアプリケーションで、WIC プラットフォームに付属の共通イメージ形式に対して提供されるプラットフォーム サポートと同等のサポートが貴社のイメージ形式にも提供されます。また、Windows Vista フォト ギャラリー、エクスプローラ、Windows フォト ビューアーでは、貴社が提供したデコーダーを使用して貴社の形式でイメージのサムネイルとプレビューを表示できます。RAW 形式の場合、より高度なイメージング アプリケーションから、貴社のデコーダーの RAW 処理機能を使用できるようになります。サポートするエンコーダー オプションを基に、貴社のエンコーダー固有の機能を公開して、アプリケーションが貴社のイメージ形式の拡張機能を最大限に利用できるようにすることができます。
WIC 対応のコーデックを開発するには、新しいインターフェイスをいくつか実装する必要があります。多くの場合、それらのインターフェイスを実装する既存のコーデックのラッパーを作成できます。コーデックをインストールする際は、いくつかのレジストリ エントリを作成して、WIC プラットフォームによりコーデックが検出されるようにし、コーデックを適切なメタデータ ハンドラーと関連付ける必要があります。また、API を呼び出して、貴社の形式のイメージと既に関連付けられている可能性がある、既定 (空) のサムネイルの縮小表示キャッシュをクリアする必要もあります。希望される場合は、Windows フォト ギャラリーが貴社のファイル拡張子を持つイメージを検出した場合に、ユーザーに貴社のコーデックをダウンロードするためのリンクを提供できます。その場合、対象となるコーデックのファイル拡張子とダウンロード サイトの URL の情報をマイクロソフトにお知らせください。
WIC プラットフォームでコーデックを開発すると、貴社のイメージ形式のユーザーにとって大きなメリットを提供できます。また、サード パーティのアプリケーションが、貴社のイメージ形式をサポートしやすくなります。
7. 詳細情報
ドキュメント:
ブログ:
ダウンロード:
WIC は、現在 Windows Vista® および Windows® 7 にインストールされていますが、Windows XP SP2 でもダウンロードしてお使いいただけます。WPF は System.Windows.Media.Imaging クラスに WIC を使用するため、WPF をインストールすると、
Web アドレスは変更される可能性があるため、ここに記載されている Web サイトに接続できない場合があります。