目次||

3.5メタデータの処理

イメージ・ファイルに格納されているデータのうち、実際のピクセル値を表しているもの以外のことを、メタデータといいます。The javax.imageio.metadataパッケージには、メタデータにアクセスするためのクラスおよびインタフェースが格納されています。

メタデータには、複雑で階層構造になったデータが含まれていることがあります。これらの構造はJava XML Document Object Model (DOM) APIを使用して表現できるので、開発者はこのインタフェースに関する知識を活用できます。

Image I/O APIでは、ストリーム・メタデータ(イメージ・ファイルに格納された全イメージに関係している)と、イメージ・メタデータ(1つのイメージだけに関係している)が区別されます。イメージを1つしか格納できないイメージ形式では、イメージ・メタデータだけが使用されます。

メタデータを取得するには、ImageReader.getStreamMetadataおよびgetImageMetadata(int imageIndex)メソッドを呼び出します。これらのメソッドからは、IIOMetadataインタフェースを実装したオブジェクトが返されます。返されるオブジェクトの実際のクラス型はImageReaderによって異なりますが、通常は、その特定の読取りプラグインのみで使用される独自のクラス型になります。このオブジェクトは、特定のイメージ形式で使用できるメタデータをできるかぎり多く格納できるように、つまり未対応のメタデータをできるかぎり少なくするように設計する必要があります。ただし、イメージ形式の仕様に忠実であろうとすると、無理が生じることがあります。メタデータにアクセスする方法が、イメージ形式ごとに限定的なものになるからです。

メタデータにアクセスする際にイメージ形式に特有のアプリケーション・コードを不要にするため、IIOMetadataオブジェクトは、内部情報をXML DOM構造の形で公開します。この構造は、さまざまな型のノードから成るツリーが基本で、各ノードには、属性セット(名前によってアクセスするString値)が入っています。子ノードを参照することもできます。

1つのプラグインでは、複数のドキュメント形式をサポートできます。それぞれは、形式の名前で区別されます。通常、個々のプラグインは、少なくとも2つのドキュメント形式をサポートします。第1の形式はcom.sun.imageio_1.0という名前の、プラグインに依存しない共通のドキュメント形式で、IIOMetadataインタフェースのクラス・コメントで定義されています。第2の形式は、各プラグインにまったく固有のドキュメント形式で、IIOMetadataオブジェクトの内部構造すべてをDOMの形で公開します。後者のドキュメント形式は、プラグインのネイティブ形式と呼ばれます。その名前を判別するには、読取りオブジェクトから返されるIIOMetadataオブジェクトのgetNativeMetadataFormatNameメソッドを呼び出します(操作方法がわかる場合には、読取りオブジェクトのインスタンスを生成するのに使用したImageReaderSpiオブジェクトの、同じ名前のメソッドを呼び出してもかまいません。この方法は、特定のドキュメント形式をサポートしているかどうかに基づいてプラグインを選択する場合に便利です)。サポートされているすべてのドキュメント形式の名前を判別するには、同様にしてgetMetadataFormatNamesメソッドを呼び出します。

IIOMetadataオブジェクトの内容は、XMLのNodeオブジェクトで成るツリーの形式でアクセスできます。アクセスするには、そのオブジェクトのgetAsTreeメソッドを呼び出します。このメソッドには、プラグインによってサポートされているドキュメント形式の名前の1つを、String引数として指定します。返されたドキュメントは、標準のXML DOMツリーとして操作できます。

一例として、XML DOMツリーの内容を出力するには、次のようなコードを使用できます。

public void displayMetadata(Node root) {
        displayMetadata(root, 0);
}

void indent(int level) {
        for (int i = 0; i < level; i++) {
                System.out.print("  ");
        }
} 

void displayMetadata(Node node, int level) {
        indent(level); // emit open tag
        System.out.print("<" + node.getNodeName());
        NamedNodeMap map = node.getAttributes();
        if (map != null) { // print attribute values
                int length = map.getLength();
                for (int i = 0; i < length; i++) {
                        Node attr = map.item(i);
                        System.out.print(" " + attr.getNodeName() +
                                         "=\"" + attr.getNodeValue() + "\"");
                }
        }

        Node child = node.getFirstChild();
        if (child != null) {
                System.out.println(">"); // close current tag
                while (child != null) { // emit child tags recursively
                        displayMetadata(child, level + 1);
                        child = child.getNextSibling();
                }
                indent(level); // emit close tag
                System.out.println("</" + node.getNodeName() + ">");
        } else {
                System.out.println("/>");
        }
}

PNGのテスト・イメージのメタデータに対してdisplayMetadataを実行すると、次のような出力が得られます。
<com.sun.imageio.png_1.0>
  <IHDR width="32" height="32" bitDepth="8" colorType="RGB"
compressionMethod="deflate" filterMethod="adaptive" interlaceMethod="none"/>
  <cHRM whitePointX="31270" whitePointY="32900" redX="64000" redY="33000"
greenX="30000" greenY="60000" blueX="15000" blueY="6000"/>
  <gAMA value="100000"/>
</com.sun.imageio.png_1.0>
この出力を見ると、このイメージにはIHDRcHRMおよびgAMAというメタデータのブロックが含まれていることがわかります。各属性値を解釈するためには、PNG形式について理解している必要があります。しかし、PNGの内部を理解できないアプリケーションであっても、これらの属性値を表示し、対話式に編集することは可能です。

3.5.1 IIOMetadataFormatインタフェース

IIOMetadataFormatオブジェクトは、メタデータのドキュメント形式について有効な構造を記述するために使用します。この記述によって制約が課せられるのは、出現してよいノードの型、特定の型のノードの子ノードになれるノードの型、特定の型のノードに出現してよい属性の名前とデータ型、そして特定の型のノードに格納できるObject値の録音テープです。XML用語で言えば、IIOMetadataFormatインタフェースによって提供される情報は、ノードの型、子、および属性について情報を提供するDTD (Document Type Definition)と、データ型について詳細な情報を提供するXML Schemaの中間に位置しています。

簡単にするため、IIOMetadataFormatで記述できるのは、有効なDTD構造のサブセットのみです。たとえば、IIOMetadataFormatで定義できる子ノードは、必ず1回出現しなければならない子ノードの順番を記述する(a, b, c)、オプションの子ノードの順番を記述する(a?, b?, c?)、子ノードを1つ選択することを記述する(a|b|c)、または1つのノード型の反復を記述する(a)*のみです。しかし、DTDでは、もっと多くの組合せを記述できます。

ノードにはテキスト・データを入れることができませんが、任意のObjectへの参照を入れることができます。IIOMetadataFormatでは、そのObjectについて、クラス型と、有効な値の列挙リストまたは範囲(これは省略可能)を指定します。配列もサポートされています。

DTDでは、属性のデータ型に指定できるのは文字列型のみです。XMLスキーマでは、単純データ型から構築した非常に複雑なデータ型を指定できます。IIOMetadataFormatは、両者の中間に位置しています。つまり、属性のデータ型として、事前に定義された単純なデータ型の1つを指定できます。整数、浮動小数点数、日付などのデータ型があります。これらのデータ型のリストも指定できます。

IIOMetadataFormatは、メタデータの表示および編集用のユーザー・インタフェースを自動的に構築するときに利用できるため、有効な構造が制限されているということは、ドキュメント形式とユーザー・インタフェース設計の対応付けの大幅な簡略化につながります。



目次||

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.