目次 | 前へ | 次へ

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 Schema では、単純データ型から構築した非常に複雑なデータ型を指定できます。IIOMetadataFormat は、両者の中間に位置しています。つまり、属性のデータ型として、事前に定義された単純なデータ型の 1 つを指定できます。整数、浮動小数点数、日付などのデータ型があります。これらのデータ型のリストも指定できます。

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



目次 | 前へ | 次へ

Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.
連絡先