Bildmetadaten

In diesem Artikel wird erläutert, wie Sie Bildmetadateneigenschaften lesen und schreiben und wie Sie Dateien mithilfe der GeotagHelper-Hilfsklasse geotagHelper geotag-Dateien erstellen.

Image-Eigenschaften

Die StorageFile.Properties-Eigenschaft gibt ein StorageItemContentProperties-Objekt zurück, das Zugriff auf inhaltsbezogene Informationen zur Datei bietet. Rufen Sie die bildspezifischen Eigenschaften ab, indem Sie GetImagePropertiesAsync aufrufen. Das zurückgegebene ImageProperties-Objekt macht Elemente verfügbar, die grundlegende Bildmetadatenfelder enthalten, z. B. den Titel des Bilds und das Aufnahmedatum.

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

Um auf einen größeren Satz von Dateimetadaten zuzugreifen, verwenden Sie das Windows-Eigenschaftensystem, eine Reihe von Dateimetadateneigenschaften, die mit einem eindeutigen Zeichenfolgenbezeichner abgerufen werden können. Erstellen Sie eine Liste mit Zeichenfolgen, und fügen Sie den Bezeichner für jede Eigenschaft hinzu, die Sie abrufen möchten. Die ImageProperties.RetrievePropertiesAsync-Methode verwendet diese Liste von Zeichenfolgen und gibt ein Wörterbuch mit Schlüssel-Wert-Paaren zurück, wobei der Schlüssel der Eigenschaftsbezeichner ist und der Wert der Eigenschaftswert ist.

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"];
}
  • Eine vollständige Liste der Windows-Eigenschaften, einschließlich der Bezeichner und des Typs für jede Eigenschaft, finden Sie unter Windows-Eigenschaften.

  • Einige Eigenschaften werden nur für bestimmte Dateicontainer und Bildcodecs unterstützt. Eine Auflistung der für jeden Bildtyp unterstützten Bildmetadaten finden Sie unter "Richtlinien für Fotometadaten".

  • Da eigenschaften, die nicht unterstützt werden, beim Abrufen möglicherweise einen NULL-Wert zurückgeben, überprüfen Sie immer auf NULL, bevor Sie einen zurückgegebenen Metadatenwert verwenden.

Geotag-Hilfsprogramm

GeotagHelper ist eine Hilfsklasse, mit der Bilder mit geografischen Daten mithilfe der Windows.Devices.Geolocation-APIs direkt kategorisiert werden können, ohne das Metadatenformat manuell analysieren oder erstellen zu müssen.

Wenn Sie bereits über ein Geopoint-Objekt verfügen, das den Ort darstellt, den Sie im Bild markieren möchten, entweder aus einer früheren Verwendung der Geolocation-APIs oder einer anderen Quelle, können Sie die Geotag-Daten festlegen, indem Sie GeotagHelper.SetGeotagAsync aufrufen und eine StorageFile und den Geopoint übergeben.

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

await GeotagHelper.SetGeotagAsync(imageFile, point);

Um die Geotagdaten mithilfe des aktuellen Standorts des Geräts festzulegen, erstellen Sie ein neues Geolocator-Objekt, und rufen Sie GeotagHelper.SetGeotagFromGeolocatorAsync auf, indem Sie den Geolocator und die datei übergeben, die markiert werden soll.

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

Rufen Sie GetGeotagAsync auf, um einen GeoPoint abzurufen, der den geografischen Speicherort einer Bilddatei darstellt.

Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);

Decodieren und Codieren von Bildmetadaten

Die fortschrittlichste Methode zum Arbeiten mit Bilddaten besteht darin, die Eigenschaften auf Datenstromebene mithilfe eines BitmapDecoder oder eines BitmapEncoder zu lesen und zu schreiben. Für diese Vorgänge können Sie windows-Eigenschaften verwenden, um die Daten anzugeben, die Sie lesen oder schreiben, aber Sie können auch die von der Windows-Imageerstellungskomponente (WIC) bereitgestellte Metadatenabfragesprache verwenden, um den Pfad zu einer angeforderten Eigenschaft anzugeben.

Zum Lesen von Bildmetadaten mit dieser Technik müssen Sie über einen BitmapDecoder verfügen, der mit dem Quellbilddateidatenstrom erstellt wurde. Informationen dazu finden Sie unter "Imaging".

Nachdem Sie über den Decoder verfügen, erstellen Sie eine Liste mit Zeichenfolgen, und fügen Sie einen neuen Eintrag für jede metadateneigenschaft hinzu, die Sie abrufen möchten, entweder mithilfe der Windows-Eigenschaftsbezeichnerzeichenfolge oder einer WIC-Metadatenabfrage. Rufen Sie die BitmapPropertiesView.GetPropertiesAsync-Methode für das BitmapProperties-Element des Decoders auf, um die angegebenen Eigenschaften anzufordern. Die Eigenschaften werden in einem Wörterbuch mit Schlüssel-Wert-Paaren zurückgegeben, die den Eigenschaftennamen oder Pfad und den Eigenschaftswert enthalten.

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;
        }
    }
}
  • Informationen zur WIC-Metadatenabfragesprache und den unterstützten Eigenschaften finden Sie unter WIC-Bildformat native Metadatenabfragen.

  • Viele Metadateneigenschaften werden nur von einer Teilmenge von Bildtypen unterstützt. GetPropertiesAsync schlägt mit dem Fehlercode 0x88982F41 fehl, wenn eine der angeforderten Eigenschaften vom dem Decoder zugeordneten Bild nicht unterstützt wird, und 0x88982F81, wenn das Bild überhaupt keine Metadaten unterstützt. Die diesen Fehlercodes zugeordneten Konstanten sind WINCODEC_ERR_PROPERTYNOTSUPPORTED und WINCODEC_ERR_UNSUPPORTEDOPERATION und werden in der Winerror.h-Headerdatei definiert.

  • Da ein Bild einen Wert für eine bestimmte Eigenschaft enthalten kann oder nicht, verwenden Sie das IDictionary.ContainsKey , um zu überprüfen, ob eine Eigenschaft in den Ergebnissen vorhanden ist, bevor Sie versuchen, darauf zuzugreifen.

Zum Schreiben von Bildmetadaten in den Datenstrom ist ein BitmapEncoder erforderlich, der der Bildausgabedatei zugeordnet ist.

Erstellen Sie ein BitmapPropertySet-Objekt , das die eigenschaftenwerte enthält, die Sie festlegen möchten. Erstellen Sie ein BitmapTypedValue-Objekt , um den Eigenschaftswert darzustellen. Dieses Objekt verwendet ein Objekt als Wert und Element der PropertyType-Aufzählung , die den Typ des Werts definiert. Fügen Sie bitmapTypedValue dem BitmapPropertySet hinzu, und rufen Sie dann BitmapProperties.SetPropertiesAsync auf, damit der Encoder die Eigenschaften in den Datenstrom schreibt.

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