Поделиться через


Общие сведения о чтении и написании метаданных изображения

В этом разделе представлен обзор использования API компонента образов Windows (WIC) для чтения и записи метаданных, внедренных в файлы изображений.

В этом разделе содержатся следующие разделы.

Необходимые условия

Чтобы понять эту тему, необходимо ознакомиться с системой метаданных WIC, как описано в обзоре метаданных WIC. Вы также должны ознакомиться с языком запросов, используемым для чтения и записи метаданных, как описано в обзоре языка запросов метаданных.

Знакомство

WIC предоставляет разработчикам приложений компоненты компонентной объектной модели (COM) для чтения и записи метаданных, внедренных в файлы изображений. Существует два способа чтения и записи метаданных:

  • Использование средства для чтения/записи запросов и выражения запроса для обращения к блокам метаданных, содержащих вложенные блоки или определённые метаданные в блоке.
  • Использование обработчика метаданных (средства чтения метаданных или записи метаданных) для доступа к вложенным блокам метаданных или определенным метаданным в блоках метаданных.

Проще всего использовать средство чтения и записи запросов и выражение запроса для доступа к метаданным. Средство чтения запросов (IWICMetadataQueryReader) используется для чтения метаданных, а средство записи запросов (IWICMetadataQueryWriter) используется для записи метаданных. Оба из них используют выражение запроса для чтения или записи требуемых метаданных. За кулисами читатель и писатель запросов используют обработчик метаданных для доступа к метаданным, описанным в выражении запроса.

Более сложный метод — прямой доступ к обработчикам метаданных. Обработчик метаданных получается из отдельных кадров с помощью средства чтения блоков (IWICMetadataBlockReader) или записи блоков (IWICMetadataBlockWriter). Доступны два типа обработчиков метаданных — читатель метаданных (IWICMetadataReader) и средство записи метаданных (IWICMetadataWriter).

Диаграмма содержимого файла изображения JPEG, приведённая ниже, используется во всех примерах этого раздела. Изображение, представленное этой схемой, было создано с помощью Microsoft Paint; Метаданные рейтинга были добавлены с помощью функции коллекции фотографий Windows Vista.

иллюстрация jpeg-изображения с метаданными оценки

Чтение Metadadata с помощью средства чтения запросов

Самый простой способ чтения метаданных — использовать интерфейс чтения запросов, IWICMetadataQueryReader. Средство чтения запросов позволяет считывать блоки метаданных и элементы в блоках метаданных с помощью выражения запроса.

Существует три способа получения средства чтения запросов: с помощью декодирования растрового изображения (IWICBitmapDecoder), через отдельные кадры (IWICBitmapFrameDecode) или через модуль записи запросов (IWICMetadataQueryWriter).

Получение средства чтения запросов

В следующем примере кода показано, как получить декодер растрового изображения из фабрики изображений и извлечь отдельный кадр. Этот код также выполняет настройку, необходимую для получения средства чтения запросов из декодированного кадра.

IWICImagingFactory *pFactory = NULL;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pFrameDecode = NULL;
IWICMetadataQueryReader *pQueryReader = NULL;
IWICMetadataQueryReader *pEmbedReader = NULL;
PROPVARIANT value;

// Initialize COM
CoInitialize(NULL);

// Initialize PROPVARIANT
PropVariantInit(&value);

//Create the COM imaging factory
HRESULT hr = CoCreateInstance(
    CLSID_WICImagingFactory,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IWICImagingFactory,
    (LPVOID*)&pFactory);

// Create the decoder
if (SUCCEEDED(hr))
{
    hr = pFactory->CreateDecoderFromFilename(
        L"test.jpg",
        NULL,
        GENERIC_READ,
        WICDecodeMetadataCacheOnDemand,
        &pDecoder);
}

// Get a single frame from the image
if (SUCCEEDED(hr))
{
    hr = pDecoder->GetFrame(
         0,  //JPEG has only one frame.
         &pFrameDecode); 
}

Декодер растрового изображения для файла test.jpg получается, используя метод CreateDecoderFromFilename фабрики изображений. В этом методе четвертый параметр устанавливается в значение WICDecodeMetadataCacheOnDemand из перечисления WICDecodeOptions. Это сообщает декоделю кэшировать метаданные, когда необходимы метаданные; либо путем получения средства чтения запросов, либо базового средства чтения метаданных. Этот параметр позволяет вам сохранить поток, необходимый для быстрого кодирования метаданных, и обеспечивает без потерь декодирование изображения в формате JPEG. Кроме того, можно использовать другое значение WICDecodeOptions, WICDecodeMetadataCacheOnLoad, которое кэширует внедренные метаданные изображения сразу после его загрузки.

Чтобы получить считыватель запросов кадра, просто вызовите метод GetMetadataQueryReader кадра. Следующий код демонстрирует этот вызов.

// Get the query reader
if (SUCCEEDED(hr))
{
    hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}

Аналогичным образом средство чтения запросов также можно получить на уровне декодера. Простой вызов метода GetMetadataQueryReader декодировщика позволяет получить средство чтения запросов декодера. Читатель запросов декодера, в отличие от читателя запросов кадра, считывает метаданные изображения, которое находится за пределами отдельных кадров. Однако этот сценарий не распространен, и собственные форматы изображений не поддерживают эту возможность. Кодеки изображений, предоставляемые WIC, читают и записывают метаданные на уровне кадра даже для однофреймовых форматов, таких как JPEG.

Чтение метаданных

Прежде чем перейти к фактическому чтению метаданных, ознакомьтесь со следующей схемой JPEG-файла, включающего внедренные блоки метаданных и фактические данные для извлечения. Эта схема предоставляет выноски для определенных блоков метаданных и элементов в изображении, предоставляя выражение запроса метаданных каждому блоку или элементу.

иллюстрация изображения JPEG с выносками метаданных

Чтобы запросить внедренные блоки метаданных или определенные элементы по имени, вызовите метод GetMetadataByName. Этот метод принимает выражение запроса и PROPVARIANT, в котором возвращается элемент метаданных. Следующий код запрашивает вложенный блок метаданных и преобразует компонент IUnknown, предоставленный значением PROPVARIANT, в средство чтения запросов при обнаружении.

if (SUCCEEDED(hr))
{
    // Get the nested IFD reader
    hr = pQueryReader->GetMetadataByName(L"/app1/ifd", &value);
    if (value.vt == VT_UNKNOWN)
    {
        hr = value.punkVal->QueryInterface(IID_IWICMetadataQueryReader, (void **)&pEmbedReader);
    }
    PropVariantClear(&value); // Clear value for new query
}

Выражение запроса "/app1/ifd" запрашивает блок IFD, вложенный в блок App1. Файл изображения JPEG содержит блок вложенных метаданных IFD, поэтому PROPVARIANT возвращается с типом переменной (vt) VT_UNKNOWN и указателем на интерфейс IUnknown (punkVal). Затем запросите интерфейс IUnknown для средства чтения запросов.

Следующий код демонстрирует новый запрос на основе нового считывателя запросов относительно вложенного блока IFD.

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetMetadataByName(L"/{ushort=18249}", &value);
    PropVariantClear(&value); // Clear value for new query
}

Выражение запроса "/{ushort=18249}" запрашивает блок IFD для оценки MicrosoftPhoto, внедренной в тег 18249. Значение PROPVARIANT теперь будет содержать тип значения VT_UI2 и значение данных 50.

Однако перед запросом к определенным значениям данных не требуется получить вложенный блок. Например, вместо того чтобы сначала выполнять запрос к вложенному IFD, а затем для оценки MicrosoftPhoto, вы можете использовать корневой блок метаданных и запрос, показанный в следующем коде, чтобы получить те же сведения.

if (SUCCEEDED(hr))
{
    hr = pQueryReader->GetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);
    PropVariantClear(&value);
}

Помимо запроса для определенных элементов метаданных в блоке метаданных, можно также перечислить все элементы метаданных в блоке метаданных (не включая элементы метаданных в вложенных блоках метаданных). Для перечисления элементов метаданных в текущем блоке используется метод средства чтения запросов GetEnumeration. Этот метод получает интерфейс IEnumString, заполненный элементами метаданных в текущем блоке. Например, следующий код перечисляет рейтинг XMP и рейтинг MicrosoftPhoto для вложенного блока IFD, полученного ранее.

IEnumString *metadataItems = NULL;

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetEnumerator(&metadataItems);
}

Дополнительные сведения о определении соответствующих тегов для различных форматов изображений и форматов метаданных см. в запросах метаданных для нативного формата изображений.

Дополнительные методы чтения запросов

Помимо чтения метаданных, вы также можете получить дополнительные сведения о средстве чтения запросов и получить метаданные с помощью других средств. Средство чтения запросов предоставляет два метода, которые предоставляют сведения о средстве чтения запросов, GetContainerFormat и GetLocation.

С помощью встроенного средства чтения запросов можно использовать GetContainerFormat для определения типа блока метаданных, и можно вызвать GetLocation, чтобы получить путь относительно корневого блока метаданных. Следующий код запрашивает встроенного читателя запросов для определения его расположения.

// Determine the metadata block format

if (SUCCEEDED(hr))
{
    hr = pEmbedReader->GetContainerFormat(&containerGUID);
}

// Determine the query reader's location
if (SUCCEEDED(hr))
{
    UINT length;
    WCHAR readerNamespace[100];
    hr = pEmbedReader->GetLocation(100, readerNamespace, &length);
}

Вызов GetContainerFormat для встроенного средства чтения запросов возвращает GUID формата метаданных IFD. Вызов GetLocation возвращает пространство имен "/app1/ifd"; предоставляет относительный путь, из которого будут выполняться последующие запросы для нового средства чтения запросов. Конечно, предыдущий код не очень полезен, но он демонстрирует, как использовать метод GetLocation GetLocation для поиска вложенных блоков метаданных.

Написание метаданных с помощью средства записи запросов

Заметка

Некоторые примеры кода, приведенные в этом разделе, не отображаются в контексте фактических шагов, необходимых для записи метаданных. Чтобы просмотреть примеры кода в контексте рабочего примера, см. руководство по повторному кодированию изображения с помощью метаданных.

 

Основным компонентом записи метаданных является модуль записи запросов (IWICMetadataQueryWriter). Модуль записи запросов позволяет задавать и удалять блоки метаданных и элементы в блоке метаданных.

Как и механизм чтения запросов, существует три способа получения механизма записи запросов: через растровый энкодер (IWICBitmapEncoder), через его отдельные кадры (IWICBitmapFrameEncode) или через быстрый энкодер метаданных (IWICFastMetadataEncoder).

Получение редактора запросов

Наиболее распространённый способ запроса применяется к отдельному кадру растрового изображения. Этот модуль записи запросов задает и удаляет блоки и элементы метаданных кадра изображения. Чтобы получить запись запросов кадра изображения, вызовите метод GetMetadataQueryWriter кадра. Следующий код демонстрирует простой вызов метода для получения записи запросов кадра.

IWICMetadataQueryWriter &pFrameQWriter = NULL;

//Obtain a query writer from the frame.
hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);

Аналогичным образом, генератор запросов также можно получить для уровня кодировщика. Простой вызов метода GetMetadataQueryWriter кодировщика получает модуль записи запросов кодировщика. Модуль записи запросов кодировщика, в отличие от записи запросов кадра, записывает метаданные для изображения за пределами отдельного кадра. Однако этот сценарий не распространен, и собственные форматы изображений не поддерживают эту возможность. Собственные кодеки изображений, предоставляемые WIC, считывают и записывают метаданные на уровне кадра даже для форматов с одним кадром, таких как JPEG.

Вы также можете получить модуль записи запросов непосредственно из фабрики образов (IWICImagingFactory). Существует два метода фабрики изображений, возвращающие модуль записи запросов: CreateQueryWriter и CreateQueryWriterFromReader.

CreateQueryWriter создает модуль записи запросов для указанного формата метаданных и поставщика. Этот модуль записи запросов позволяет записывать метаданные для определенного формата метаданных и добавлять его в изображение. Следующий код демонстрирует вызов CreateQueryWriter для создания модуля записи запросов XMP.

IWICMetadataQueryWriter *pXMPWriter = NULL;

// Create XMP block
GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriter(
        GUID_MetadataFormatXMP,
        &vendor,
        &pXMPWriter);

В этом примере понятное имя GUID_MetadataFormatXMP используется в качестве параметра guidMetadataFormat. Он представляет GUID формата метаданных XMP, а поставщик представляет созданный корпорацией Майкрософт обработчик. Кроме того, null можно передать в качестве параметра pguidVendor с теми же результатами, если ни один другой обработчик XMP не существует. Если настраиваемый обработчик XMP установлен вместе с собственным обработчиком XMP, передача NULL для поставщика приведет к тому, что модуль записи запросов возвращает наименьший GUID.

CreateQueryWriterFromReader похож на метод CreateQueryWriter, за исключением того, что он предварительно заполняет новый модуль записи запросов данными, предоставленными средством чтения запросов. Это полезно для повторной кодировки изображения при сохранении существующих метаданных или для удаления нежелательных метаданных. Следующий код демонстрирует вызов CreateQueryWriterFromReader.

hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);

// Copy metadata using query readers
if(SUCCEEDED(hr) && pFrameQReader)
{
    IWICMetadataQueryWriter *pNewWriter = NULL;

    GUID vendor = GUID_VendorMicrosoft;
    hr = pFactory->CreateQueryWriterFromReader(
        pFrameQReader,
        &vendor,
        &pNewWriter);

Добавление метаданных

После получения инструмента для записи запросов его можно использовать для добавления блоков метаданных и элементов. Для записи метаданных используется метод SetMetadataByName от автора запросов. SetMetadataByName принимает два параметра: выражение запроса (wzName) и указатель на PROPVARIANT (pvarValue). Выражение запроса определяет блок или элемент, который нужно установить, а PROPVARIANT предоставляет фактическое значение данных для этого.

В следующем примере показано, как добавить заголовок с помощью средства записи запросов XMP, полученного ранее с помощью метода CreateQueryWriter.

// Write metadata to the XMP writer
if (SUCCEEDED(hr))
{
    PROPVARIANT value;
    PropVariantInit(&value);

    value.vt = VT_LPWSTR;
    value.pwszVal = L"Metadata Test Image.";
   
    hr = pXMPWriter->SetMetadataByName(L"/dc:title", &value);

    PropVariantClear(&value);
}

В этом примере для типа значения (vt) задано значение VT_LPWSTR, указывающее, что строка будет использоваться в качестве значения данных. Поскольку значение имеет тип строки, используется pwszVal для установки заголовка. SetMetadataByName затем вызывается с помощью выражения запроса "/dc:title" и вновь заданного PROPVARIANT. Выражение запроса, используемое, указывает, что свойство 'заголовок' в схеме цифровой камеры (dc) должно быть задано. Обратите внимание, что выражение не является "/xmp/dc:title"; это связано с тем, что составитель запросов уже специфичен для XMP и не содержит встроенный блок XMP, на который указывало бы "/xmp/dc:title".

До этого момента вы фактически не добавили метаданные в кадр изображения. Вы просто заполнили генератор запросов данными. Чтобы добавить в кадр блок метаданных, представленный средством записи запросов, снова вызовите SetMetadataByName, указав средство записи запросов в качестве значения PROPVARIANT. Это фактически копирует метаданные из конструктора запросов в кадр изображения. В следующем коде показано, как добавить метаданные с использованием ранее полученного модуля записи запросов XMP в корневой блок метаданных кадра.

// Get the frame's query writer and write the XMP query writer to it
if (SUCCEEDED(hr))
{
    hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);

    // Copy the metadata in the XMP query writer to the frame
    if (SUCCEEDED(hr))
    {
        PROPVARIANT value;

        PropVariantInit(&value);
        value.vt = VT_UNKNOWN;
        value.punkVal = pXMPWriter;
        value.punkVal->AddRef();

        hr = pFrameQWriter->SetMetadataByName(L"/", &value);

        PropVariantClear(&value);
    }
}

В этом примере используется тип значения (vt) VT_UNKOWN, что указывает на тип значения интерфейса COM. Затем модуль записи запросов XMP (piXMPWriter) используется в качестве значения PROPVARIANT, добавляя ссылку на него с помощью метода AddRef. Наконец, модуль записи запросов XMP устанавливается путем вызова метода SetMetadataBy Name кадра и передачи выражения запроса "/", указывающего корневой блок, и только что заданный PROPVARIANT.

Заметка

Если кадр уже содержит блок метаданных, который вы пытаетесь добавить, добавленные метаданные будут добавлены и существующие метаданные перезаписаны.

 

Удаление метаданных

Модуль записи запросов также позволяет удалять метаданные, вызывая метод RemoveMetadataByName. RemoveMetadataByName принимает выражение запроса и удаляет блок метаданных или элемент, если он существует. В следующем коде показано, как удалить название, которое было добавлено ранее.

if (SUCCEEDED(hr))
{
    hr = pFrameQWriter->RemoveMetadataByName(L"/xmp/dc:title");
}

В следующем коде показано, как удалить весь блок метаданных XMP.

if (SUCCEEDED(hr))
{
    hr = pFrameQWriter->RemoveMetadataByName(L"/xmp");
}

Копирование метаданных для повторной кодирования

Заметка

Код в этом разделе действителен только в том случае, если форматы исходного и целевого изображений одинаковы. Невозможно скопировать все метаданные изображения в одной операции при кодировке в другой формат изображения.

 

Чтобы сохранить метаданные при повторном кодировании изображения в одном формате изображения, существуют методы для копирования всех метаданных в одной операции. Каждая из этих операций соответствует аналогичному шаблону; каждый задает метаданные декодированного кадра непосредственно в новый кадр, закодированный.

Предпочтительным способом копирования метаданных является инициализация блоковой записи нового кадра с использованием блокового считывателя декодированного кадра. Следующий код демонстрирует этот метод.

if (SUCCEEDED(hr) && formatsEqual)
{
    // Copy metadata using metadata block reader/writer
    if (SUCCEEDED(hr))
    {
        pFrameDecode->QueryInterface(
            IID_IWICMetadataBlockReader,
            (void**)&pBlockReader);
    }
    if (SUCCEEDED(hr))
    {
        pFrameEncode->QueryInterface(
            IID_IWICMetadataBlockWriter,
            (void**)&pBlockWriter);
    }
    if (SUCCEEDED(hr))
    {
        pBlockWriter->InitializeFromBlockReader(pBlockReader);
    }
}

В этом примере средство чтения блоков и модуль записи блоков получаются из исходного кадра и целевого кадра соответственно. Затем модуль записи блоков инициализируется из средства чтения блоков. Это инициализирует средство чтения блоков с его предварительно заполненными метаданными.

Другим способом копирования метаданных является запись блока метаданных, на который ссылается средство чтения запросов с помощью средства записи запросов кодировщика. Следующий код демонстрирует этот метод.

if (SUCCEEDED(hr) && formatsEqual)
{
    hr = pFrameDecode->GetMetadataQueryReader(&pFrameQReader);

    // Copy metadata using query readers
    if(SUCCEEDED(hr))
    {
        hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
        if (SUCCEEDED(hr))
        {
            PropVariantClear(&value);
            value.vt=VT_UNKNOWN;
            value.punkVal=pFrameQReader;
            value.punkVal->AddRef();
            hr = pFrameQWriter->SetMetadataByName(L"/", &value);
            PropVariantClear(&value);
        }
    }
}

Здесь средство чтения запросов получается из декодированного кадра, а затем используется в качестве значения свойства PROPVARIANT с типом значения, заданным для VT_UNKNOWN. Запрашивающий модуль для кодировщика получен, и выражение запроса "/" используется для установки метаданных в корневом навигационном пути. Этот метод также можно использовать при настройке вложенных блоков метаданных, изменив выражение запроса в нужное расположение.

Аналогичным образом, вы можете создать модуль записывания запросов на основе средства чтения запросов декодированного кадра, используя метод CreateQueryWriterFromReader фабрики изображений. Модуль записи запросов, созданный в этой операции, предварительно заполнится метаданными из средства чтения запросов и затем может быть установлен в рамке. Следующий код демонстрирует операцию копирования CreateQueryWriterFromReader.

IWICMetadataQueryWriter *pNewWriter = NULL;

GUID vendor = GUID_VendorMicrosoft;
hr = pFactory->CreateQueryWriterFromReader(
    pFrameQReader,
    &vendor,
    &pNewWriter);

if (SUCCEEDED(hr))
{
    // Get the frame's query writer
    hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
}

// Set the query writer to the frame.
if (SUCCEEDED(hr))
{
    PROPVARIANT value;

    PropVariantInit(&value);
    value.vt = VT_UNKNOWN;
    value.punkVal = pNewWriter;
    value.punkVal->AddRef();
    hr = pFrameQWriter->SetMetadataByName(L"/",&value);
}

Этот метод использует отдельный модуль записи запросов, который основан на данных средства чтения запросов. Затем этот новый генератор запросов устанавливается в рамке.

Опять же, эти операции для копирования метаданных работают только в том случае, если исходные и целевые образы имеют одинаковый формат. Это связано с тем, что различные форматы изображений хранят блоки метаданных в разных расположениях. Например, как JPEG, так и TIFF поддерживают блоки метаданных XMP. В изображениях JPEG блок XMP находится в корневом блоке метаданных, как показано в обзоре метаданных WIC. Однако на изображении TIFF блок XMP вложен в корневой блок IFD. На следующей схеме показаны различия между изображением JPEG и изображением TIFF с одинаковыми метаданными рейтинга.

Сравнение форматов jpeg и tiff.

Быстрая кодировка метаданных

Для записи в него новых метаданных не всегда требуется повторно кодировать изображение. Метаданные также можно записать с помощью быстрого кодировщика метаданных. Быстрый кодировщик метаданных может записывать ограниченный объем метаданных в изображение без повторной кодирования изображения. Осуществляется через запись новых метаданных в свободной области, предоставленной некоторыми форматами метаданных. Собственные форматы метаданных, поддерживающие заполнение метаданных, — Exif, IFD, GPS и XMP.

Добавление заполнений в блоки метаданных

Прежде чем выполнять быструю кодировку метаданных, необходимо иметь место в блоке метаданных для записи дополнительных метаданных. Если в существующем заполнении недостаточно места для записи новых метаданных, быстрое кодирование метаданных завершится ошибкой. Чтобы добавить заполнение метаданных на изображение, необходимо повторно закодировать изображение. Вы можете добавить заполнение так же, как вы бы добавили любой другой элемент метаданных, используя выражение запроса, если блок метаданных поддерживает его. В следующем примере показано, как добавить заполнение в блок IFD, внедренный в блок App1.

if (SUCCEEDED(hr))
{
    // Add metadata padding
    PROPVARIANT padding;

    PropVariantInit(&padding);
    padding.vt = VT_UI4;
    padding.uiVal = 4096; // 4KB

    hr = pFrameQWriter->SetMetadataByName(L"/app1/ifd/PaddingSchema:padding", &padding);

    PropVariantClear(&padding);
}

Чтобы добавить заполнение, создайте PROPVARIANT типа VT_UI4 и значение, соответствующее количеству байтов заполнения. Обычное значение равно 4096 байтам. Запросы метаданных для JPEG, TIFF и JPEG-XR находятся в этой таблице.

Формат метаданных Запрос метаданных JPEG TIFF, запрос метаданных JPEG-XR
IFD /app1/ifd/PaddingSchema:Padding /ifd/PaddingSchema:Padding
EXIF /app1/ifd/exif/PaddingSchema:Padding /ifd/exif/PaddingSchema:Padding
XMP /xmp/PaddingSchema:Padding /ifd/xmp/PaddingSchema:Padding
GPS /app1/ifd/gps/PaddingSchema:Padding /ifd/gps/PaddingSchema:Padding

 

Получение быстрого кодировщика метаданных

При наличии изображения с заполнением метаданных можно получить быстрый кодировщик метаданных с помощью методов фабрики изображений CreateFastMetadataEncoderFromDecoder и CreateFastMetadataEncoderFromFrameDecode.

Как подразумевает имя, CreateFastMetadataEncoderFromDecoder создает быстрый кодировщик метаданных для метаданных уровня декодера. Собственные форматы изображений, предоставляемые WIC, не поддерживают метаданные уровня декодера, но этот метод предоставляется в случае разработки такого формата изображения в будущем.

Более распространенный сценарий — получить быстрый кодировщик метаданных из кадра изображения с помощью CreateFastMetadataEncoderFromFrameDecode. Следующий код получает быструю метаинформацию декодированного кадра, изменяя значение рейтинга в блоке App1.

if (SUCCEEDED(hr))
{
    IWICFastMetadataEncoder *pFME = NULL;
    IWICMetadataQueryWriter *pFMEQW = NULL;

    hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
        pFrameDecode, 
        &pFME);
}

Использование кодировщика быстрых метаданных

Из кодировщика быстрых метаданных можно получить средство записи запросов. Это позволяет создавать метаданные с помощью выражения запроса, как показано ранее. После установки метаданных в постановщике запросов примените ускоренный кодировщик метаданных, чтобы завершить обновление метаданных. Следующий код демонстрирует настройку и фиксацию изменений метаданных

    if (SUCCEEDED(hr))
    {
        hr = pFME->GetMetadataQueryWriter(&pFMEQW);
    }

    if (SUCCEEDED(hr))
    {
        // Add additional metadata
        PROPVARIANT value;

        PropVariantInit(&value);

        value.vt = VT_UI4;
        value.uiVal = 99;
        hr = pFMEQW->SetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);

        PropVariantClear(&value);
    }

    if (SUCCEEDED(hr))
    {
        hr = pFME->Commit();
    }
}

Если фиксация не удастся по какой-либо причине, необходимо повторно перекодировать изображение, чтобы гарантировать, что новые метаданные добавляются в изображение.

концептуальные

Обзор компонента Windows Imaging

Обзор метаданных WIC

Обзор языка запросов метаданных

Обзор расширяемости метаданных

Как: Повторное кодирование изображения JPEG с использованием метаданных