Metadados de imagemImage Metadata

Este artigo mostra como ler e gravar propriedades de metadados de imagem e como geotag arquivos usando a classe de utilitário GeotagHelper .This article shows how to read and write image metadata properties and how to geotag files using the GeotagHelper utility class.

Propriedades da imagemImage properties

A propriedade StorageFile.Properties retorna um objeto StorageItemContentProperties que fornece acesso às informações relacionadas ao conteúdo sobre o arquivo.The StorageFile.Properties property returns a StorageItemContentProperties object that provides access to content-related information about the file. Obtenha as propriedades específicas da imagem chamando GetImagePropertiesAsync.Get the image-specific properties by calling GetImagePropertiesAsync. O objeto retornado ImageProperties expõe membros que contêm campos de metadados de imagem básicos, como o título da imagem e a data de captura.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
    }
}

Para acessar um conjunto maior de metadados do arquivo, use o Windows Property System, um conjunto de propriedades de metadados de arquivo que pode ser recuperado com um identificador de cadeia de caracteres exclusivo.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. Crie uma lista de cadeias de caracteres e adicione o identificador para cada propriedade que você deseja recuperar.Create a list of strings and add the identifier for each property you want to retrieve. O método ImageProperties.RetrievePropertiesAsync usa essa lista de cadeias de caracteres e retorna um dicionário de pares de chave/valor onde a chave é o identificador da propriedade e o valor é o valor da propriedade.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"];
}
  • Para obter uma lista completa das Propriedades do Windows, incluindo os identificadores e o tipo de cada propriedade, consulte Propriedades do Windows.For a complete list of Windows Properties, including the identifiers and type for each property, see Windows Properties.

  • Algumas propriedades só são suportadas para determinados codecs de imagem e contêineres de arquivos.Some properties are only supported for certain file containers and image codecs. Para obter uma lista dos metadados de imagem com suporte para cada tipo de imagem, consulte Políticas de Metadados de Fotos.For a listing of the image metadata supported for each image type, see Photo Metadata Policies.

  • Como as propriedades que não são suportadas podem retornar um valor nulo quando recuperado, sempre verifique para null antes de usar um valor de metadados retornados.Because properties that are unsupported may return a null value when retrieved, always check for null before using a returned metadata value.

GeotagHelperGeotag helper

GeotagHelper é uma classe de utilitário que facilita a marcação de imagens com dados geográficos usando as APIs Windows.Devices.Geolocation diretamente, sem precisar analisar ou construir manualmente o formato de metadados.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.

Se você já tiver um objeto Geopoint que representa o local que deseja marcar na imagem, de uma utilização anterior das APIs de geolocalização ou de alguma outra fonte, poderá definir os dados de marca de localização chamando GeotagHelper.SetGeotagAsync e passando StorageFile e o Geopoint.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);

Para definir os dados de marca de localização usando a localização atual do dispositivo, crie um novo objeto Geolocator e chame GeotagHelper.SetGeotagFromGeolocatorAsync passando Geolocator e o arquivo a ser marcado.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);
}

Para obter um GeoPoint que represente o local de um arquivo de imagem com marca de localização, chame GetGeotagAsync.To get a GeoPoint representing the geotagged location of an image file, call GetGeotagAsync.

Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);

Decodificar e codificar metadados de imagemDecode and encode image metadata

A maneira mais avançada de trabalhar com dados de imagem é ler e gravar as propriedades no nível do fluxo usando um BitmapDecoder ou um 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. Para essas operações, você pode usar Propriedades do Windows para especificar os dados que está lendo ou gravando, mas também pode usar a linguagem de consulta de metadados fornecida pelo Windows Imaging Component (WIC) para especificar o caminho para uma propriedade solicitada.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.

Ler metadados de imagem usando essa técnica exige que você tenha um BitmapDecoder que foi criado com o fluxo de arquivo de imagem de origem.Reading image metadata using this technique requires you to have a BitmapDecoder that was created with the source image file stream. Para obter informações sobre como fazer isso, consulte Imagens.For information on how to do this, see Imaging.

Assim que você tiver o decodificador, crie uma lista de cadeias de caracteres e adicione uma nova entrada para cada propriedade de metadados que deseja recuperar usando a cadeia de caracteres de identificador da Propriedade do Windows ou uma consulta de metadados do 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. Chame o método BitmapPropertiesView.GetPropertiesAsync no membro BitmapProperties do decodificador para solicitar as propriedades especificadas.Call the BitmapPropertiesView.GetPropertiesAsync method on the decoder's BitmapProperties member to request the specified properties. As propriedades são retornadas em um dicionário de pares de chave/valor que contém o nome ou caminho da propriedade e o valor da propriedade.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;
        }
    }
}
  • Para obter informações sobre a linguagem de consulta de metadados do WIC e as propriedades com suporte, consulte Consultas de metadados nativos de formato de imagem do WIC.For information on the WIC metadata query language and the properties supported, see WIC image format native metadata queries.

  • Muitas propriedades de metadados são suportadas apenas por um subconjunto de tipos de imagem.Many metadata properties are only supported by a subset of image types. GetPropertiesAsync falhará com o código de erro 0x88982F41 se não houver suporte para uma das propriedades solicitadas pela imagem associada ao decodificador e 0x88982F81 se a imagem não der suporte a metadados.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. As constantes associadas a esses códigos de erro são WINCODEC _ Err _ PROPERTYNOTSUPPORTED e WINCODEC _ Err _ UNSUPPORTEDOPERATION e são definidas no arquivo de cabeçalho 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.

  • Como uma imagem pode ou não conter um valor de uma propriedade específica, use o IDictionary.ContainsKey para verificar se uma propriedade está presente nos resultados antes de tentar acessá-la.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.

Gravar metadados de imagem no fluxo requer um BitmapEncoder associado ao arquivo de saída da imagem.Writing image metadata to the stream requires a BitmapEncoder associated with the image output file.

Crie um objeto BitmapPropertySet para conter os valores de propriedade que você deseja definir.Create a BitmapPropertySet object to contain the property values you want set. Crie um objeto BitmapTypedValue para representar o valor da propriedade.Create a BitmapTypedValue object to represent the property value. Esse objeto usa um object como o valor e o membro da enumeração PropertyType que define o tipo do valor.This object uses an object as the value and member of the PropertyType enumeration that defines the type of the value. Adicione BitmapTypedValue a BitmapPropertySet e, em seguida, chame BitmapProperties.SetPropertiesAsync para fazer com que o codificador grave as propriedades no fluxo.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;
        }
    }
}