画像のメタデータImage Metadata

この記事では、画像のメタデータ プロパティを読み取ったり書き込んだりする方法のほか、GeotagHelper ユーティリティ クラスを使ってファイルに位置情報タグを設定する方法について説明します。This article shows how to read and write image metadata properties and how to geotag files using the GeotagHelper utility class.

画像のプロパティImage properties

ファイルの内容に関連した情報には、StorageFile.Properties プロパティから返される StorageItemContentProperties オブジェクトを使ってアクセスできます。The StorageFile.Properties property returns a StorageItemContentProperties object that provides access to content-related information about the file. 画像に固有のプロパティを取得するには、GetImagePropertiesAsync を呼び出します。Get the image-specific properties by calling GetImagePropertiesAsync. それによって返される ImageProperties オブジェクトは、画像のタイトルやキャプチャの日付など、基本的な画像メタデータのフィールドを含んだメンバーを公開します。The returned ImageProperties object exposes members that contain basic image metadata fields, like the title of the image and the capture date.

private async void GetImageProperties(StorageFile imageFile)
{
    ImageProperties props = await imageFile.Properties.GetImagePropertiesAsync();

    string title = props.Title;
    if (title == null)
    {
        // Format does not support, or image does not contain Title property
    }

    DateTimeOffset date = props.DateTaken;
    if (date == null)
    {
        // Format does not support, or image does not contain DateTaken property
    }
}

さらに広範なファイル メタデータにアクセスするには、一意の文字列識別子で取得できるファイル メタデータ プロパティが集約された Windows プロパティ システムを使います。To access a larger set of file metadata, use the Windows Property System, a set of file metadata properties that can be retrieved with a unique string identifier. 文字列のリストを作成し、取得する必要のある各プロパティの識別子を追加してください。Create a list of strings and add the identifier for each property you want to retrieve. ImageProperties.RetrievePropertiesAsync メソッドは、この文字列のリストを引数として受け取ってキー/値ペアのディクショナリを返します。このディクショナリのキーがプロパティ識別子で、ディクショナリの値がそのプロパティの値になります。The ImageProperties.RetrievePropertiesAsync method takes this list of strings and returns a dictionary of key/value pairs where the key is the property identifier and the value is the property value.

ImageProperties props = await imageFile.Properties.GetImagePropertiesAsync();

var requests = new System.Collections.Generic.List<string>();
requests.Add("System.Photo.Orientation");
requests.Add("System.Photo.Aperture");

IDictionary<string, object> retrievedProps = await props.RetrievePropertiesAsync(requests);

ushort orientation;
if (retrievedProps.ContainsKey("System.Photo.Orientation"))
{
    orientation = (ushort)retrievedProps["System.Photo.Orientation"];
}

double aperture;
if (retrievedProps.ContainsKey("System.Photo.Aperture"))
{
    aperture = (double)retrievedProps["System.Photo.Aperture"];
}
  • Windows のプロパティの完全な一覧 (プロパティごとの識別子と型を含む) については、「Windows プロパティ」をご覧ください。For a complete list of Windows Properties, including the identifiers and type for each property, see Windows Properties.

  • 一部のプロパティは、特定のファイル コンテナーや特定の画像コーデックでのみサポートされます。Some properties are only supported for certain file containers and image codecs. 画像の種類ごとのサポートされるメタデータについては、「フォト メタデータ ポリシー」をご覧ください。For a listing of the image metadata supported for each image type, see Photo Metadata Policies.

  • サポート対象外のプロパティを取得しようとすると null 値が返される場合があります。返されたメタデータの値を使う前に必ず、null のチェックを行ってください。Because properties that are unsupported may return a null value when retrieved, always check for null before using a returned metadata value.

位置情報タグ ヘルパーGeotag helper

GeotagHelper は、地理データを含んだ画像へのタグ付けを支援するユーティリティ クラスです。Windows.Devices.Geolocation API を直接使って簡単にタグを設定することができます。メタデータの形式を手動で解析したり構築したりする必要はありません。GeotagHelper is a utility class that makes it easy to tag images with geographic data using the Windows.Devices.Geolocation APIs directly, without having to manually parse or construct the metadata format.

地理位置情報 API の使用後など、タグの設定対象となる画像の位置情報を表す Geopoint オブジェクトが取得済みで、そのオブジェクトが既に存在する場合は、GeotagHelper.SetGeotagAsyncStorageFileGeopoint を渡して呼び出すことで位置情報タグ データを設定できます。If you already have a Geopoint object representing the location you want to tag in the image, either from a previous use of the geolocation APIs or some other source, you can set the geotag data by calling GeotagHelper.SetGeotagAsync and passing in a StorageFile and the Geopoint.

var point = new Geopoint(
new BasicGeoposition
{
    Latitude = 48.8567,
    Longitude = 2.3508,
});

await GeotagHelper.SetGeotagAsync(imageFile, point);

デバイスの現在位置を使って位置情報タグ データを設定するには、Geolocator オブジェクトを新たに作成し、GeotagHelper.SetGeotagFromGeolocatorAsync の引数に Geolocator とタグの設定対象となるファイルとを指定して呼び出します。To set the geotag data using the device's current location, create a new Geolocator object and call GeotagHelper.SetGeotagFromGeolocatorAsync passing in the Geolocator and the file to be tagged.

var locator = new Geolocator();

// Shows the user consent UI if needed
var accessStatus = await Geolocator.RequestAccessAsync();
if (accessStatus == GeolocationAccessStatus.Allowed)
{
    await GeotagHelper.SetGeotagFromGeolocatorAsync(imageFile, locator);
}

位置情報タグで示された画像ファイルの地理的位置を表す GeoPoint を取得するには、GetGeotagAsync を呼び出します。To get a GeoPoint representing the geotagged location of an image file, call GetGeotagAsync.

Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);

画像メタデータのデコードとエンコードDecode and encode image metadata

画像データを操作する最も高度な方法は、BitmapDecoder または BitmapEncoder を使って、プロパティの読み取りと書き込みをストリーム レベルで行うことです。The most advanced way of working with image data is to read and write the properties on the stream level using a BitmapDecoder or a BitmapEncoder. これらの操作では、読み取りまたは書き込みの対象データを Windows プロパティを使って指定できるほか、要求するプロパティのパスを Windows Imaging Component (WIC) のメタデータ クエリ言語を使って指定することもできます。For these operations you can use Windows Properties to specify the data you are reading or writing, but you can also use the metadata query language provided by the Windows Imaging Component (WIC) to specify the path to a requested property.

この方法で画像のメタデータを読み取るには、ソース画像ファイル ストリームを使って作成された BitmapDecoder が必要です。Reading image metadata using this technique requires you to have a BitmapDecoder that was created with the source image file stream. この方法については、「イメージング」をご覧ください。For information on how to do this, see Imaging.

デコーダーを取得したら、文字列のリストを作成し、Windows プロパティの識別子文字列または WIC メタデータ クエリを使って、取得する各メタデータ プロパティの新しいエントリを追加します。Once you have the decoder, create a list of strings and add a new entry for each metadata property you want to retrieve, using either the Windows Property identifier string or a WIC metadata query. 特定のプロパティを要求するには、デコーダーの BitmapProperties メンバーの BitmapPropertiesView.GetPropertiesAsync メソッドを呼び出します。Call the BitmapPropertiesView.GetPropertiesAsync method on the decoder's BitmapProperties member to request the specified properties. 要求したプロパティが、プロパティ名 (またはパス) とプロパティ値を含んだキー/値ペアのディクショナリとして返されます。The properties are returned in a dictionary of key/value pairs containing the property name or path and the property value.

private async void ReadImageMetadata(BitmapDecoder bitmapDecoder)
{

    var requests = new System.Collections.Generic.List<string>();
    requests.Add("System.Photo.Orientation"); // Windows property key for EXIF orientation
    requests.Add("/xmp/dc:creator"); // WIC metadata query for Dublin Core creator

    try
    {
        var retrievedProps = await bitmapDecoder.BitmapProperties.GetPropertiesAsync(requests);

        ushort orientation;
        if (retrievedProps.ContainsKey("System.Photo.Orientation"))
        {
            orientation = (ushort)retrievedProps["System.Photo.Orientation"].Value;
        }

        string creator;
        if (retrievedProps.ContainsKey("/xmp/dc:creator"))
        {
            creator = (string)retrievedProps["/xmp/dc:creator"].Value;
        }
    }
    catch (Exception err)
    {
        switch (err.HResult)
        {
            case unchecked((int)0x88982F41): // WINCODEC_ERR_PROPERTYNOTSUPPORTED
                                             // The file format does not support the requested metadata.
                break;
            case unchecked((int)0x88982F81): // WINCODEC_ERR_UNSUPPORTEDOPERATION
                                             // The file format does not support any metadata.
            default:
                throw err;
        }
    }
}
  • WIC メタデータ クエリ言語とサポートされるプロパティについては、「WIC ネイティブ イメージ形式メタデータのクエリ」をご覧ください。For information on the WIC metadata query language and the properties supported, see WIC image format native metadata queries.

  • メタデータのプロパティの多くは、サポートされる画像の種類に限りがあります。Many metadata properties are only supported by a subset of image types. GetPropertiesAsync イメージがメタデータをまったくサポートしない場合は、デコーダーと 0x88982F81 に関連付けられているイメージで要求されたプロパティの 1 つはサポートされていない場合は、エラー コード 0x88982F41 で失敗します。GetPropertiesAsync will fail with the error code 0x88982F41 if one of the requested properties is not supported by the image associated with the decoder and 0x88982F81 if the image does not support metadata at all. これらのエラー コードに関連付けられている定数は WINCODEC_ERR_PROPERTYNOTSUPPORTED と WINCODEC_ERR_UNSUPPORTEDOPERATION とは、winerror.h ヘッダー ファイルで定義します。The constants associated with these error codes are WINCODEC_ERR_PROPERTYNOTSUPPORTED and WINCODEC_ERR_UNSUPPORTEDOPERATION and are defined in the winerror.h header file.

  • 特定のプロパティの値が画像に存在するかどうかはわからないので、IDictionary.ContainsKey を使って、結果にプロパティが存在するかどうかを確かめたうえでアクセスしてください。Because an image may or may not contain a value for a particular property, use the IDictionary.ContainsKey to verify that a property is present in the results before attempting to access it.

画像のメタデータをストリームに書き込むには、画像の出力ファイルに関連付けられている BitmapEncoder が必要です。Writing image metadata to the stream requires a BitmapEncoder associated with the image output file.

設定対象プロパティの値を保持する BitmapPropertySet オブジェクトを作成します。Create a BitmapPropertySet object to contain the property values you want set. プロパティの値を表す BitmapTypedValue オブジェクトを作成します。Create a BitmapTypedValue object to represent the property value. このオブジェクトでは、値の型を定義する PropertyType 列挙型の値およびメンバーとして object を使います。This object uses an object as the value and member of the PropertyType enumeration that defines the type of the value. BitmapTypedValueBitmapPropertySet に追加したうえで、BitmapProperties.SetPropertiesAsync を呼び出すと、エンコーダーがプロパティをストリームに書き込みます。Add the BitmapTypedValue to the BitmapPropertySet and then call BitmapProperties.SetPropertiesAsync to cause the encoder to write the properties to the stream.

private async void WriteImageMetadata(BitmapEncoder bitmapEncoder)
{
    var propertySet = new Windows.Graphics.Imaging.BitmapPropertySet();
    var orientationValue = new Windows.Graphics.Imaging.BitmapTypedValue(
        1, // Defined as EXIF orientation = "normal"
        Windows.Foundation.PropertyType.UInt16
        );

    propertySet.Add("System.Photo.Orientation", orientationValue);

    try
    {
        await bitmapEncoder.BitmapProperties.SetPropertiesAsync(propertySet);
    }
    catch (Exception err)
    {
        switch (err.HResult)
        {
            case unchecked((int)0x88982F41): // WINCODEC_ERR_PROPERTYNOTSUPPORTED
                                             // The file format does not support this property.
                break;
            default:
                throw err;
        }
    }
}