Alcune informazioni riguardano un prodotto in versione preliminare che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Informazioni sul codec di estensione HEIF (High Efficiency Image Format) disponibile tramite WIC. Per scaricare il codec di estensione da Microsoft Store, vedi Estensione dell'immagine HEIF.
Due GUID in formato pixel consentono ai visualizzatori di foto di recuperare rappresentazioni alternative di un'immagine HEIF.
Solo profondità
GUID_WICPixelFormat8bppDepth
Solo guadagno
GUID_WICPixelFormat8bppGain
Per altre info su questi formati, vedi Panoramica dei formati pixel nativi.
L'enumerazione WICHeifCompressionOption delle opzioni di codifica consente alle app di scegliere il formato di compressione da usare durante la creazione di un file di immagine HEIF.
Uso del codec di estensione HEIF
Se hai un'app che usa WIC, puoi usare un GUID in formato pixel per richiedere la rappresentazione dell'immagine. La tua app può verificare se un decodificatore WIC supporta un formato pixel specifico usando il metodo IWICBitmapSourceTransform::GetClosestPixelFormat .
Ad esempio, se un'immagine viene convertita in una bitmap che usa il formato pixel GUID_WICPixelFormat24bppRGB , significa che la bitmap contiene informazioni sul colore rosso, verde e blu per ogni pixel. (8 bit per componente colore. GUID_WICPixelFormat32bppRGBA aggiunge informazioni alfa (trasparenza) a ogni pixel. Il formato pixel GUID_WICPixelFormat8bppAlpha viene usato per le bitmap che contengono solo informazioni alfa a 8 bit per ogni pixel.
Informazioni approfondite e di guadagno per HEIF
Per i file HEIF (High Efficiency Image Format), il formato pixel GUID_WICPixelFormat8bppDepth è rilevante. Funziona in modo analogo a GUID_WICPixelFormat8bppAlpha. Ad eccezione del fatto che mentre alfa specifica la trasparenza dei pixel, la profondità specifica la distanza relativa di pixel dal visualizzatore dell'immagine.
In una bitmap che usa GUID_WICPixelFormat8bppDepth, la bitmap contiene un valore a 8 bit con informazioni di profondità per pixel. Il valore 0 indica che il pixel localizzato nella rappresentazione bitmap a colori dell'immagine si trova più vicino al visualizzatore; e un valore pari a 255 indica che il pixel localizzato nella bitmap del colore si trova più lontano dal visualizzatore.
Anche per HEIF, esiste un formato di pixel denominato GUID_WICPixelFormat8bppGain. Analogamente ai formati pixel per alfa e profondità, GUID_WICPixelFormat8bppGain fornisce un valore a 8 bit per pixel. Lo scopo delle informazioni di guadagno è quello di specificare un guadagno di luminosità che può essere applicato ai pixel in formato RGB: convertendo in modo efficace un'immagine RGB normale in un'immagine HDR (High Dynamic Range). Le informazioni di guadagno vengono esposte così come sono. L'app può usare i metadati Exif o XMP nell'immagine HEIF per determinare il modello di fotocamera che ha generato il guadagno. Attualmente, le informazioni di guadagno sono incluse solo nei file HEIF creati dai dispositivi iOS Apple recenti.
Non esiste alcuna profondità predefinita o ottenere informazioni per le immagini. La chiamata a IWICBitmapSourceTransform::CopyPixels richiede una rappresentazione di guadagno o profondità di un'immagine che non contiene tali informazioni genererà un errore WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT .
Opzioni di compressione
L'enumerazione WICHeifCompressionOption viene usata per specificare un'opzione denominata HeifCompressionMethod quando si codifica una bitmap nel formato HEIF.
HEIF è un contenitore, simile a TIFF, che può usare metodi di compressione diversi. Il metodo di compressione predefinito è High-Efficiency Video Codec (HEVC). I file HEIF compressi con HEVC usano in genere l'estensione del .heic file. Con il valore enumerazione WICHeifCompressionAV1 , sarà possibile specificare che il codec AV1 deve essere usato. I file HEIF che usano AV1 per la compressione usano in genere l'estensione di .avif file.
HEIF tenterà di eseguire determinate modifiche, ad esempio rotazione e ritaglio, senza ricomprimere l'immagine. Puoi usare il valore di enumerazione WICHeifCompressionNone per imporre che l'immagine non venga ricompressa. Se l'immagine deve essere ricompressa, l'operazione commit restituirà WINCODEC_ERR_UNSUPPORTEDOPERATION se è stato specificato WICHeifCompressionNone .
I codec HEVC e AV1 potrebbero non essere disponibili in tutti i PC. È possibile scaricare questi codec da Microsoft Store. Per verificare se è installato HEVC o AV1, è possibile usare la funzione MFTEnumEx per eseguire una query sulla presenza di un codificatore video rispettivamente per i formati MFVideoFormat_HEVC e MFVideoFormat_AV1.
Esempi di codice
Questi esempi di codice usano le librerie di implementazione di Windows (WIL). Un modo pratico per installare WIL consiste nel passare a Visual Studio, fare clic su Project>Manage NuGet Packages (Gestisci pacchetti NuGet).>Sfoglia, digita o incolla Microsoft.Windows.ImplementationLibrary nella casella di ricerca, seleziona l'elemento nei risultati della ricerca e quindi fai clic su Installa per installare il pacchetto per il progetto.
Esempio 1: Profondità
In questo esempio viene illustrato come verificare se sono disponibili informazioni approfondite e come recuperarlo.
using namespace wil;
bool IsPixelFormatSupported(_In_ IWICBitmapSourceTransform* bitmap,
REFWICPixelFormatGUID proposedPixelFormat)
{
WICPixelFormatGUID closestPixelFormat = proposedPixelFormat;
if (SUCCEEDED(bitmap->GetClosestPixelFormat(&closestPixelFormat)) &&
closestPixelFormat == proposedPixelFormat)
{
return true;
}
return false;
}
bool IsDepthAvailable(_In_ IWICBitmapSourceTransform* bitmap)
{
return IsPixelFormatSupported(bitmap, GUID_WICPixelFormat8bppDepth);
}
HRESULT GetDepthBitmap(_In_ IWICBitmapFrameDecode* frame, unique_cotaskmem_ptr<BYTE[]>& bitmap)
{
bitmap.reset();
com_ptr_nothrow<IWICBitmapSourceTransform> frameTransform;
RETURN_IF_FAILED(com_query_to_nothrow(frame, &frameTransform));
// Check whether depth information is available for this image. If there's no depth
// information, then just return an empty bitmap.
if (IsDepthAvailable(frameTransform.get()))
{
UINT width;
UINT height;
RETURN_IF_FAILED(frame->GetSize(&width, &height));
size_t bitmapSize;
RETURN_IF_FAILED(SizeTMult(width, height, &bitmapSize));
bitmap = make_unique_cotaskmem_nothrow<BYTE[]>(bitmapSize);
RETURN_IF_NULL_ALLOC(bitmap);
WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat8bppDepth;
RETURN_IF_FAILED(frameTransform->CopyPixels(nullptr, width, height,
&pixelFormat, WICBitmapTransformRotate0, width, bitmapSize, bitmap.get()));
}
return S_OK;
}
Esempio 2: Guadagno
In questo esempio viene illustrato come verificare se sono disponibili informazioni di guadagno e come recuperarlo. In questo esempio viene riutilizzata la funzione IsPixelFormatSupported illustrata nell'esempio 1.
using namespace wil;
bool IsGainAvailable(_In_ IWICBitmapSourceTransform* bitmap)
{
return IsPixelFormatSupported(bitmap, GUID_WICPixelFormat8bppGain);
}
HRESULT GetGainBitmap(_In_ IWICBitmapFrameDecode* frame, unique_cotaskmem_ptr<BYTE[]>& bitmap)
{
bitmap.reset();
com_ptr_nothrow<IWICBitmapSourceTransform> frameTransform;
RETURN_IF_FAILED(com_query_to_nothrow(frame, &frameTransform));
// Check whether gain information is available for this image. If there's no gain
// information, then just return an empty bitmap.
if (IsGainAvailable(frameTransform.get()))
{
UINT width;
UINT height;
RETURN_IF_FAILED(frame->GetSize(&width, &height));
size_t bitmapSize;
RETURN_IF_FAILED(SizeTMult(width, height, &bitmapSize));
bitmap = make_unique_cotaskmem_nothrow<BYTE[]>(bitmapSize);
RETURN_IF_NULL_ALLOC(bitmap);
WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat8bppGain;
RETURN_IF_FAILED(frameTransform->CopyPixels(nullptr, width, height,
&pixelFormat, WICBitmapTransformRotate0, width, bitmapSize, bitmap.get()));
}
return S_OK;
}
Esempio 3: Specificare che è necessario usare la compressione AV1
Questo esempio illustra come usare la compressione AV1 per codificare un file HEIF, creando un .avif file.
using namespace wil;
HRESULT EncodeSourceAsAvif(IWICBitmapSource* source, IWICStream* outputStream, IWICImagingFactory* factory)
{
com_ptr_nothrow<IWICBitmapEncoder> encoder;
RETURN_IF_FAILED(factory->CreateEncoder(GUID_ContainerFormatHeif, nullptr, &encoder));
RETURN_IF_FAILED(encoder->Initialize(outputStream, WICBitmapEncoderCacheInMemory));
com_ptr_nothrow<IWICBitmapFrameEncode> outputFrame;
com_ptr_nothrow<IPropertyBag2> encoderOptions;
RETURN_IF_FAILED(encoder->CreateNewFrame(&outputFrame, &encoderOptions));
// Configure the output frame to compress the source image using the AV1 encoder.
PROPBAG2 option{};
option.pstrName = L"HeifCompressionMethod";
VARIANT propertyValue{};
propertyValue.vt = VT_UI1;
propertyValue.bVal = static_cast<BYTE>(WICHeifCompressionAV1);
RETURN_IF_FAILED(encoderOptions->Write(1, &option, &propertyValue));
RETURN_IF_FAILED(outputFrame->Initialize(encoderOptions.get()));
RETURN_IF_FAILED(outputFrame->WriteSource(source, nullptr));
// Do the actual encoding of the source image. If the AV1 encoder is missing,
// then this call fails.
RETURN_IF_FAILED(outputFrame->Commit());
RETURN_IF_FAILED(encoder->Commit());
return S_OK;
}
Esempio 4: Specifica che la compressione non è consentita
Questo esempio mostra come salvare un'immagine in un contenitore HEIF e applicare rotazione e ritaglio all'immagine; ma imponendo che l'immagine non venga compressa. Se l'origine è già in formato HEVC o AV1, questa operazione avrà esito positivo. Tuttavia, se l'origine è una bitmap non elaborata o in un altro formato, la funzione restituirà un errore se la codifica non è consentita.
using namespace wil;
// Rotate and optionally crop the source image, and produce a HEIF image file as output.
// If the input parameter allowEncoding is false, and the image needs to be encoded,
// then this function will return WINCODEC_ERR_UNSUPPORTEDOPERATION.
HRESULT RotateAndCropSource(
IWICBitmapSource* source,
IWICStream* outputStream,
IWICImagingFactory* factory,
bool allowCompression,
WICBitmapTransformOptions transformOptions,
WICRect* cropRectangle = nullptr)
{
com_ptr_nothrow<IWICBitmapEncoder> encoder;
RETURN_IF_FAILED(factory->CreateEncoder(GUID_ContainerFormatHeif, NULL, &encoder));
RETURN_IF_FAILED(encoder->Initialize(outputStream, WICBitmapEncoderCacheInMemory));
com_ptr_nothrow<IWICBitmapFrameEncode> outputFrame;
com_ptr_nothrow<IPropertyBag2> encoderOptions;
RETURN_IF_FAILED(encoder->CreateNewFrame(&outputFrame, &encoderOptions));
VARIANT propertyValue{};
if (!allowCompression)
{
// Specify that compression of the image is not allowed.
PROPBAG2 option{};
option.pstrName = L"HeifCompressionMethod";
propertyValue.vt = VT_UI1;
propertyValue.bVal = static_cast<BYTE>(WICHeifCompressionNone);
RETURN_IF_FAILED(encoderOptions->Write(1, &option, &propertyValue));
}
if (transformOptions != WICBitmapTransformRotate0)
{
PROPBAG2 option{};
option.pstrName = L"BitmapTransform";
propertyValue.vt = VT_UI1;
propertyValue.bVal = static_cast<BYTE>(transformOptions);
RETURN_IF_FAILED(encoderOptions->Write(1, &option, &propertyValue));
}
RETURN_IF_FAILED(outputFrame->Initialize(encoderOptions.get()));
RETURN_IF_FAILED(outputFrame->WriteSource(source, cropRectangle));
// Generate the HEIF file. If the image needs to be compressed, this call fails.
RETURN_IF_FAILED(outputFrame->Commit());
RETURN_IF_FAILED(encoder->Commit());
return S_OK;
}
Questo percorso di apprendimento ha lo scopo di spiegare agli studenti come distribuire intelligenza artificiale nei dispositivi perimetrali usando servizi di Azure.