Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье показано, как считывать и записывать свойства метаданных изображения и как выполнять геотагирование файлов с помощью класса служебной программы GeotagHelper.
Свойства изображения
Свойство StorageFile.Properties возвращает объект StorageItemContentProperties, предоставляющий доступ к сведениям о файле, связанным с содержимым. Получите свойства, относящиеся к изображению, вызвав GetImagePropertiesAsync. Возвращенный объект ImageProperties предоставляет элементы, содержащие основные поля метаданных изображения, такие как заголовок изображения и дата записи.
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;
}
Чтобы получить доступ к более большому набору метаданных файла, используйте систему свойств Windows, набор свойств метаданных файла, которые можно получить с уникальным идентификатором строки. Создайте список строк и добавьте идентификатор для каждого свойства, которое требуется извлечь. Метод ImageProperties.RetrievePropertiesAsync принимает этот список строк и возвращает словарь пар key/value, где ключ является идентификатором свойства, и значением является значение свойства.
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"];
}
}
Полный список свойств Windows, включая идентификаторы и тип для каждого свойства, см. в разделе Windows Свойства.
Некоторые свойства поддерживаются только для определенных контейнеров файлов и кодеков изображений. Список метаданных изображения, поддерживаемых для каждого типа изображения, см. в разделе "Политики метаданных фотографий".
Так как свойства, неподдерживаемые, могут возвращать значение NULL при извлечении, всегда проверяйте значение NULL перед использованием возвращаемого значения метаданных.
Вспомогательный геотаг
GeotagHelper — это служебный класс, который упрощает тег изображений с географическими данными с помощью Windows. Devices.Geolocation API напрямую, не выполняя ручной анализ или создание формата метаданных.
Если у вас уже есть объект Geopoint, представляющий местоположение, которое вы хотите пометить на изображении, полученный либо при предыдущем использовании API геолокации, либо из другого источника, вы можете задать данные геотега, вызвав GeotagHelper.SetGeotagAsync и передав StorageFile и Geopoint.
private async void SetGeoDataFromPoint(StorageFile imageFile)
{
var point = new Geopoint(
new BasicGeoposition
{
Latitude = 48.8567,
Longitude = 2.3508,
});
await GeotagHelper.SetGeotagAsync(imageFile, point);
}
Чтобы задать данные геотега, используя текущее местоположение устройства, создайте новый объект Geolocator и вызовите GeotagHelper.SetGeotagFromGeolocatorAsync, передав Geolocator и файл, для которого нужно задать геотег.
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);
}
}
Чтобы использовать API SetGeotagFromGeolocatorAsync, необходимо включить функцию устройства расположения в манифест приложения.
Перед вызовом SetGeotagFromGeolocatorAsync необходимо вызвать RequestAccessAsync, чтобы убедиться, что пользователь предоставил приложению разрешение на использование своего расположения.
Дополнительные сведения о географическом размещении и картах API см. в разделе "Управление картами".
Чтобы получить GeoPoint, представляющую географическое расположение файла изображения, вызовите GetGeotagAsync.
private async void GetGeoData(StorageFile imageFile)
{
Geopoint geoPoint = await GeotagHelper.GetGeotagAsync(imageFile);
}
Декодирование и кодирование метаданных изображения
Самым сложным способом работы с данными изображения является чтение и запись свойств на уровне потока с помощью BitmapDecoder или BitmapEncoder. Для этих операций можно использовать свойства Windows для указания данных, которые вы читаете или записываете, но также можно использовать язык запросов метаданных, предоставляемый компонентом Windows визуализации (WIC), чтобы указать путь к запрошенным свойствам.
Для чтения метаданных изображения с помощью данного метода необходимо иметь BitmapDecoder, который был создан с использованием потока файла исходного изображения. Сведения о том, как это сделать, см. в разделе "Создание, изменение и сохранение растровых изображений".
После создания декодировщика создайте список строк и добавьте новую запись для каждого свойства метаданных, которое вы хотите получить, используя строку идентификатора свойства Windows или запрос метаданных WIC. Вызовите метод BitmapPropertiesView.GetPropertiesAsync у члена декодера BitmapProperties, чтобы запросить указанные свойства. Свойства возвращаются в словаре пар "ключ-значение", содержащих имя свойства или путь и значение свойства.
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;
}
}
}
Сведения о языке запросов к метаданным WIC и поддерживаемых свойствах см. в разделе Запросы к собственным метаданным формата изображений WIC.
Многие свойства метаданных поддерживаются только подмножеством типов изображений. GetPropertiesAsync завершится ошибкой с кодом ошибки 0x88982F41 если одно из запрошенных свойств не поддерживается изображением, связанным с декодером, и 0x88982F81, если изображение не поддерживает метаданные вообще. Константами, связанными с этими кодами ошибок, являются WINCODEC_ERR_PROPERTYNOTSUPPORTED и WINCODEC_ERR_UNSUPPORTEDOPERATION; они определены в заголовочном файле winerror.h.
Поскольку изображение может как содержать, так и не содержать значение для конкретного свойства, используйте IDictionary.ContainsKey, чтобы убедиться, что свойство присутствует в результатах, прежде чем пытаться получить к нему доступ.
Для записи метаданных изображения в поток требуется BitmapEncoder , связанный с выходным файлом изображения.
Создайте объект BitmapPropertySet, чтобы содержать значения свойств, которые требуется задать. Создайте объект BitmapTypedValue для представления значения свойства. Этот объект использует object в качестве значения и члена PropertyType, определяющего тип значения. Добавьте BitmapTypedValue в BitmapPropertySet , а затем вызовите BitmapProperties.SetPropertiesAsync , чтобы кодировщик записывал свойства в поток.
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;
}
}
}
Дополнительные сведения о том, какие свойства поддерживаются для каких типов файлов изображений, см. в разделах Свойства Windows, Политики метаданных фотографий и Собственные запросы метаданных формата изображений WIC.
SetPropertiesAsync завершится ошибкой с кодом ошибки 0x88982F41 если одно из запрошенных свойств не поддерживается изображением, связанным с кодировщиком.
Связанные темы
Windows developer