Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come leggere e scrivere le proprietà dei metadati delle immagini e come georeferenziare i file usando la classe di utilità GeotagHelper.
Proprietà dell'immagine
La proprietà StorageFile.Properties restituisce un oggetto StorageItemContentProperties che fornisce accesso alle informazioni correlate al contenuto sul file. Ottenere le proprietà specifiche dell'immagine chiamando GetImagePropertiesAsync. L'oggetto restituito ImageProperties espone membri che contengono campi di metadati dell'immagine di base, ad esempio il titolo dell'immagine e la data di acquisizione.
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;
}
Per accedere a un set di metadati di file più ampio, usare il Windows Property System, un set di proprietà dei metadati di file che possono essere recuperate con un identificatore di stringa univoco. Creare un elenco di stringhe e aggiungere l'identificatore per ogni proprietà da recuperare. Il metodo ImageProperties.RetrievePropertiesAsync accetta questo elenco di stringhe e restituisce un dizionario di coppie chiave/valore in cui la chiave è l'identificatore della proprietà e il valore è il valore della proprietà.
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"];
}
}
Per un elenco completo delle proprietà di Windows, inclusi gli identificatori e il tipo per ogni proprietà, vedere Windows Proprietà.
Alcune proprietà sono supportate solo per determinati contenitori di file e codec immagine. Per un elenco dei metadati dell'immagine supportati per ogni tipo di immagine, vedere Criteri dei metadati delle foto.
Poiché le proprietà non supportate possono restituire un valore Null durante il recupero, verificare sempre la presenza di valori Null prima di usare un valore di metadati restituito.
Assistente geotag
GeotagHelper è una classe di utilità che consente di aggiungere facilmente dati geografici alle immagini usando direttamente le API Windows.Devices.Geolocation, senza dover analizzare o creare manualmente il formato dei metadati.
Se si dispone già di un oggetto
private async void SetGeoDataFromPoint(StorageFile imageFile)
{
var point = new Geopoint(
new BasicGeoposition
{
Latitude = 48.8567,
Longitude = 2.3508,
});
await GeotagHelper.SetGeotagAsync(imageFile, point);
}
Per impostare i dati del geotag usando la posizione corrente del dispositivo, creare un nuovo oggetto Geolocator e chiamare GeotagHelper.SetGeotagFromGeolocatorAsync passando il Geolocator e il file da contrassegnare.
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);
}
}
Devi includere la funzionalità del dispositivo di posizione nel manifesto dell'app per usare l'API SetGeotagFromGeolocatorAsync .
Devi chiamare RequestAccessAsync prima di chiamare SetGeotagFromGeolocatorAsync per assicurarsi che l'utente abbia concesso all'app l'autorizzazione per usare la propria posizione.
Per altre informazioni sulle API di georilevazione e mappe, vedere Controllo mappa.
Per ottenere un geopoint che rappresenta la posizione geografica di un file di immagine, chiamare GetGeotagAsync.
private async void GetGeoData(StorageFile imageFile)
{
Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);
}
Decodificare e codificare i metadati dell'immagine
Il modo più avanzato per usare i dati delle immagini consiste nel leggere e scrivere le proprietà a livello di flusso usando un BitmapDecoder o un BitmapEncoder. Per queste operazioni è possibile utilizzare Windows Proprietà per specificare i dati letti o scritti, ma è anche possibile utilizzare il linguaggio di query dei metadati fornito dal componente di creazione immagine Windows (WIC) per specificare il percorso di una proprietà richiesta.
Per leggere i metadati dell'immagine usando questa tecnica è necessario disporre di un BitmapDecoder creato con il flusso del file di immagine di origine. Per informazioni su come eseguire questa operazione, vedere Creare, modificare e salvare immagini bitmap.
Una volta ottenuto il decodificatore, creare un elenco di stringhe e aggiungere una nuova voce per ogni proprietà di metadati che si desidera recuperare, usando la stringa identificativa della proprietà di Windows oppure una query di metadati WIC. Chiama il metodo BitmapPropertiesView.GetPropertiesAsync sul membro BitmapProperties del decodificatore per richiedere le proprietà specificate. Le proprietà vengono restituite in un dizionario di coppie chiave/valore contenenti il nome o il percorso della proprietà e il valore della proprietà.
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;
}
}
}
Per informazioni sul linguaggio di query dei metadati WIC e sulle proprietà supportate, vedere Query sui metadati nativi in formato immagine WIC.
Molte proprietà dei metadati sono supportate solo da un subset di tipi di immagine. GetPropertiesAsync avrà esito negativo con il codice di errore 0x88982F41 se una delle proprietà richieste non è supportata dall'immagine associata al decodificatore e 0x88982F81 se l'immagine non supporta affatto i metadati. Le costanti associate a questi codici di errore sono WINCODEC_ERR_PROPERTYNOTSUPPORTED e WINCODEC_ERR_UNSUPPORTEDOPERATION e sono definite nel file di intestazione winerror.h.
Poiché un'immagine può contenere o meno un valore per una determinata proprietà, usare IDictionary.ContainsKey per verificare che nei risultati sia presente una proprietà prima di tentare di accedervi.
La scrittura dei metadati dell'immagine nel flusso richiede un BitmapEncoder associato al file di output dell'immagine.
Creare un oggetto BitmapPropertySet per contenere i valori delle proprietà da impostare. Creare un oggetto BitmapTypedValue per rappresentare il valore della proprietà. Questo oggetto usa un object come valore e membro dell'enumerazione PropertyType che definisce il tipo del valore. Aggiungere BitmapTypedValue a BitmapPropertySet e quindi chiamare BitmapProperties.SetPropertiesAsync per fare in modo che il codificatore scriva le proprietà nel flusso.
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;
}
}
}
Per informazioni dettagliate su quali proprietà sono supportate per quali tipi di file immagine, vedere Proprietà di Windows, Criteri dei metadati delle foto e query di metadati nativi del formato immagine WIC.
SetPropertiesAsync avrà esito negativo con il codice di errore 0x88982F41 se una delle proprietà richieste non è supportata dall'immagine associata al codificatore.