Métadonnées d’image

Cet article explique comment lire et écrire des propriétés de métadonnées d’image et comment géotagiser des fichiers à l’aide de la classe utilitaire GeotagHelper.

Propriétés d’image

La propriété StorageFile.Properties renvoie un objet StorageItemContentProperties qui fournit l’accès aux informations relatives au contenu sur le fichier. Obtenez les propriétés spécifiques à l’image en appelant GetImagePropertiesAsync. L’objet retourné ImageProperties expose les membres qui contiennent des champs de métadonnées d’image de base, comme le titre de l’image et la date de capture.

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 dateTaken = props.DateTaken;
}

Pour accéder à un plus grand ensemble de métadonnées de fichier, utilisez le système de propriétés Windows, un ensemble de propriétés de métadonnées de fichier qui peuvent être récupérées avec un identificateur de chaîne unique. Créez une liste de chaînes et ajoutez l’identificateur pour chaque propriété que vous souhaitez récupérer. La méthode ImageProperties.RetrievePropertiesAsync prend cette liste de chaînes et retourne un dictionnaire de paires clé/valeur où la clé est l’identificateur de propriété et la valeur est la valeur de la propriété.

private async void GetWindowsProperties(StorageFile imageFile)
{
    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"];
    }
}
  • Pour obtenir la liste complète des propriétés Windows, y compris les identificateurs et le type de chaque propriété, consultez Windows Propriétés.

  • Certaines propriétés sont uniquement prises en charge pour certains conteneurs de fichiers et codecs d’image. Pour obtenir la liste des métadonnées d’image prises en charge pour chaque type d’image, consultez Stratégies de métadonnées de photo.

  • Étant donné que les propriétés qui ne sont pas prises en charge peuvent retourner une valeur Null lors de la récupération, vérifiez toujours la valeur Null avant d’utiliser une valeur de métadonnées retournée.

Assistant de géolocalisation

GeotagHelper est une classe utilitaire qui facilite la balise des images avec des données géographiques à l’aide du Windows. Devices.Geolocation API directement, sans avoir à analyser manuellement ou à construire le format de métadonnées.

Si vous disposez déjà d’un objet Geopoint représentant l’emplacement que vous souhaitez baliser dans l’image, qu’il soit issu d’une utilisation antérieure des API de géolocalisation ou d’une autre source, vous pouvez définir les données de géobalisage en appelant GeotagHelper.SetGeotagAsync et en lui passant un StorageFile et le Geopoint.

private async void SetGeoDataFromPoint(StorageFile imageFile)
{
    var point = new Geopoint(
        new BasicGeoposition
        {
            Latitude = 48.8567,
            Longitude = 2.3508,
        });

    await GeotagHelper.SetGeotagAsync(imageFile, point);
}

Pour définir les données de géolocalisation à l'aide de l'emplacement actuel de l'appareil, créez un objet Geolocator et appelez GeotagHelper.SetGeotagFromGeolocatorAsync en passant le Geolocator et le fichier à baliser.

private async void SetGeoDataFromGeolocator(StorageFile imageFile)
{
    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);
    }
}
  • Vous devez inclure la fonctionnalité d’appareil emplacement dans le manifeste de votre application afin d’utiliser l’API SetGeotagFromGeolocatorAsync.

  • Vous devez appeler RequestAccessAsync avant d’appeler SetGeotagFromGeolocatorAsync pour vous assurer que l’utilisateur a accordé à votre application l’autorisation d’utiliser son emplacement.

  • Pour plus d’informations sur la géolocalisation et les API de mappage, consultez Contrôle de carte.

Pour obtenir un GeoPoint représentant l’emplacement géographique d’un fichier image, appelez GetGeotagAsync.

private async void GetGeoData(StorageFile imageFile)
{
    Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);
}

Décoder et encoder les métadonnées d’image

La méthode la plus avancée d’utilisation des données d’image consiste à lire et à écrire les propriétés au niveau du flux à l’aide d’un BitmapDecoder ou d’un BitmapEncoder. Pour ces opérations, vous pouvez utiliser Windows Propriétés pour spécifier les données que vous lisez ou écrivez, mais vous pouvez également utiliser le langage de requête de métadonnées fourni par le composant WIC (Windows Imaging Component) pour spécifier le chemin d’accès à une propriété demandée.

La lecture des métadonnées d’image à l’aide de cette technique vous oblige à disposer d’un BitmapDecoder créé avec le flux de fichiers image source. Pour plus d’informations sur la procédure à suivre, consultez Créer, modifier et enregistrer des images bitmap.

Une fois que vous avez le décodeur, créez une liste de chaînes et ajoutez une nouvelle entrée pour chaque propriété de métadonnées que vous souhaitez récupérer, à l’aide de la chaîne d’identificateur de propriété Windows ou d’une requête de métadonnées WIC. Appelez la méthode BitmapPropertiesView.GetPropertiesAsync sur le membre BitmapProperties du décodeur pour demander les propriétés spécifiées. Les propriétés sont renvoyées dans un dictionnaire de paires clé-valeur contenant le nom ou le chemin d’accès de la propriété, ainsi que sa valeur.

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;
        }
    }
}
  • Pour plus d’informations sur le langage de requête de métadonnées WIC et les propriétés prises en charge, consultez les requêtes de métadonnées natives au format d’image WIC.

  • De nombreuses propriétés de métadonnées ne sont prises en charge que par un sous-ensemble de types d’images. GetPropertiesAsync échoue avec le code d’erreur 0x88982F41 si l’une des propriétés demandées n’est pas prise en charge par l’image associée au décodeur et 0x88982F81 si l’image ne prend pas en charge les métadonnées du tout. Les constantes associées à ces codes d’erreur sont WINCODEC_ERR_PROPERTYNOTSUPPORTED et WINCODEC_ERR_UNSUPPORTEDOPERATION et sont définies dans le fichier d’en-tête winerror.h.

  • Étant donné qu’une image peut contenir ou non une valeur pour une propriété particulière, utilisez IDictionary.ContainsKey pour vérifier qu’une propriété est présente dans les résultats avant de tenter de l’accéder.

L’écriture de métadonnées d’image dans le flux nécessite un BitmapEncoder associé au fichier de sortie d’image.

Créez un objet BitmapPropertySet pour contenir les valeurs de propriété que vous souhaitez définir. Créez un objet BitmapTypedValue pour représenter la valeur de propriété. Cet objet utilise un objet object comme valeur et membre de l’énumération PropertyType qui définit le type de la valeur. Ajoutez BitmapTypedValue à BitmapPropertySet , puis appelez BitmapProperties.SetPropertiesAsync pour que l’encodeur écrive les propriétés dans le flux.

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;
        }
    }
}