Compartir a través de


Metadatos de imagen

En este artículo se muestra cómo leer y escribir propiedades de metadatos de imagen y cómo geotag los archivos mediante la clase de utilidad GeotagHelper.

Propiedades de la imagen

La propiedad StorageFile.Properties devuelve un objeto StorageItemContentProperties que proporciona acceso a información relacionada con el contenido sobre el archivo. Obtenga las propiedades específicas de la imagen mediante una llamada a GetImagePropertiesAsync. El objeto ImageProperties devuelto expone miembros que contienen campos de metadatos de imagen básicos, como el título de la imagen y la fecha de captura.

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 obtener acceso a un conjunto mayor de metadatos de archivo, use el Sistema de propiedades de Windows, un conjunto de propiedades de metadatos de archivo que se pueden recuperar con un identificador de cadena único. Cree una lista de cadenas y agregue el identificador de cada propiedad que quiera recuperar. El método ImageProperties.RetrievePropertiesAsync toma esta lista de cadenas y devuelve un diccionario de pares clave-valor donde la clave es el identificador de propiedad y el valor es el valor de propiedad.

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 obtener una lista completa de las propiedades de Windows, incluidos los identificadores y el tipo de cada propiedad, vea Propiedades de Windows.

  • Algunas propiedades solo se admiten para determinados contenedores de archivos y códecs de imagen. Para obtener una lista de los metadatos de imagen admitidos para cada tipo de imagen, consulte Directivas de metadatos de fotos.

  • Dado que las propiedades que no se admiten pueden devolver un valor NULL cuando se recuperan, compruebe siempre null antes de usar un valor de metadatos devuelto.

Asistente de geotag

GeotagHelper es una clase de utilidad que facilita la etiquetado de imágenes con datos geográficos mediante las API Windows.Devices.Geolocation directamente, sin tener que analizar ni construir manualmente el formato de metadatos.

Si ya tiene un objeto Geopoint que representa la ubicación que desea etiquetar en la imagen, ya sea desde un uso anterior de las API de geolocalización u otro origen, puede establecer los datos de geotag llamando a GeotagHelper.SetGeotagAsync y pasando un StorageFile y el Geopoint.

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

await GeotagHelper.SetGeotagAsync(imageFile, point);

Para establecer los datos de geotag mediante la ubicación actual del dispositivo, cree un nuevo objeto Geolocator y llame a GeotagHelper.SetGeotagFromGeolocatorAsync pasando el Geolocator y el archivo que se va a etiquetar.

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 obtener un GeoPoint que represente la ubicación geográfica de un archivo de imagen, llame a GetGeotagAsync.

Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);

Descodificar y codificar metadatos de imagen

La forma más avanzada de trabajar con datos de imagen es leer y escribir las propiedades en el nivel de secuencia mediante bitmapDecoder o bitmapEncoder. Para estas operaciones, puedes usar propiedades de Windows para especificar los datos que estás leyendo o escribiendo, pero también puedes usar el lenguaje de consulta de metadatos proporcionado por el componente de creación de imágenes de Windows (WIC) para especificar la ruta de acceso a una propiedad solicitada.

La lectura de metadatos de imagen mediante esta técnica requiere tener un bitmapDecoder que se creó con la secuencia de archivos de imagen de origen. Para obtener información sobre cómo hacerlo, consulte Creación de imágenes.

Una vez que tenga el descodificador, cree una lista de cadenas y agregue una nueva entrada para cada propiedad de metadatos que quiera recuperar, mediante la cadena de identificador de propiedad de Windows o una consulta de metadatos wiC. Llame al método BitmapPropertiesView.GetPropertiesAsync en el miembro BitmapProperties del descodificador para solicitar las propiedades especificadas. Las propiedades se devuelven en un diccionario de pares clave-valor que contienen el nombre de propiedad o la ruta de acceso y el valor de propiedad.

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 obtener información sobre el lenguaje de consulta de metadatos de WIC y las propiedades admitidas, consulte Consultas de metadatos nativos con formato de imagen WIC.

  • Muchas propiedades de metadatos solo son compatibles con un subconjunto de tipos de imagen. GetPropertiesAsync producirá un error con el código de error 0x88982F41 si una de las propiedades solicitadas no es compatible con la imagen asociada al descodificador y 0x88982F81 si la imagen no admite metadatos en absoluto. Las constantes asociadas a estos códigos de error se WINCODEC_ERR_PROPERTYNOTSUPPORTED y WINCODEC_ERR_UNSUPPORTEDOPERATION y se definen en el archivo de encabezado winerror.h.

  • Dado que una imagen puede contener o no un valor para una propiedad determinada, use IDictionary.ContainsKey para comprobar que una propiedad está presente en los resultados antes de intentar acceder a ella.

La escritura de metadatos de imagen en la secuencia requiere un bitmapEncoder asociado al archivo de salida de imagen.

Cree un objeto BitmapPropertySet para contener los valores de propiedad que desee establecer. Cree un objeto BitmapTypedValue para representar el valor de la propiedad. Este objeto usa un objeto como valor y miembro de la enumeración PropertyType que define el tipo del valor. Agregue BitmapTypedValue a BitmapPropertySet y, a continuación, llame a BitmapProperties.SetPropertiesAsync para que el codificador escriba las propiedades en la secuencia.

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;
        }
    }
}
  • Para obtener más información sobre qué propiedades se admiten para qué tipos de archivo de imagen, consulta Propiedades de Windows, Directivas de metadatos de fotos y consultas de metadatos nativos con formato de imagen WIC.

  • SetPropertiesAsync producirá un error con el código de error 0x88982F41 si una de las propiedades solicitadas no es compatible con la imagen asociada al codificador.