-
Notifications
You must be signed in to change notification settings - Fork 437
WIC I O Functions
DirectXTex |
---|
These functions use the Windows Imaging Component (WIC) to read or write an image file. There are built-in WIC codecs in Windows for .BMP
, .PNG
, .GIF
, .TIFF
, .JPEG
, and JPEG-XR / HD Photo images. Some containers (.GIF
and .TIFF
) can contain multi-frame bitmaps files.
WIC is not supported on Linux or Windows Subsystem for Linux, so these functions are not supported for non-Win32 platforms. WIC2 is supported on Xbox One and Xbox Series X|S.
Returns the TexMetadata metadata from a WIC-supported bitmap file.
HRESULT GetMetadataFromWICMemory( const void* pSource, size_t size,
WIC_FLAGS flags, TexMetadata& metadata,
std::function<void(IWICMetadataQueryReader*)> getMQR = nullptr );
HRESULT GetMetadataFromWICFile( const wchar_t* szFile,
WIC_FLAGS flags, TexMetadata& metadata,
std::function<void(IWICMetadataQueryReader*)> getMQR = nullptr );
Loads a WIC-supported bitmap file.
HRESULT LoadFromWICMemory( const void* pSource, size_t size,
WIC_FLAGS flags, TexMetadata* metadata, ScratchImage& image,
std::function<void(IWICMetadataQueryReader*)> getMQR = nullptr );
HRESULT LoadFromWICFile( const wchar_t* szFile,
WIC_FLAGS flags, TexMetadata* metadata, ScratchImage& image,
std::function<void(IWICMetadataQueryReader*)> getMQR = nullptr );
Saves a single image or a set of images to a WIC-supported bitmap file. The caller provides the desired WIC container format to use via guidContainerFormat (see GetWICCodec for a helper). There is an optional targetFormat to specify a desired WIC pixel format (which will result in an E_FAIL
if not supported by the WIC codec)
HRESULT SaveToWICMemory( const Image& image,
WIC_FLAGS flags, REFGUID guidContainerFormat,
Blob& blob, const GUID* targetFormat = nullptr,
std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
HRESULT SaveToWICMemory( const Image* images, size_t nimages,
WIC_FLAGS flags, REFGUID guidContainerFormat,
Blob& blob, const GUID* targetFormat = nullptr,
std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
HRESULT SaveToWICFile( const Image& image,
WIC_FLAGS flags, REFGUID guidContainerFormat,
const wchar_t* szFile, const GUID* targetFormat = nullptr,
std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
HRESULT SaveToWICFile( const Image* images, size_t nimages,
WIC_FLAGS flags, REFGUID guidContainerFormat,
const wchar_t* szFile, const GUID* targetFormat = nullptr,
std::function<void(IPropertyBag2*)> setCustomProps = nullptr );
These functions can only write images using the subset of DXGI_FORMAT
values that map directly to a WIC native pixel format.
DXGI_FORMAT | WIC Format |
---|---|
DXGI_FORMAT_R32G32B32A32_FLOAT | GUID_WICPixelFormat128bppRGBAFloat |
DXGI_FORMAT_R16G16B16A16_FLOAT | GUID_WICPixelFormat64bppRGBAHalf |
DXGI_FORMAT_R16G16B16A16_UNORM | GUID_WICPixelFormat64bppRGBA |
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM | GUID_WICPixelFormat32bppRGBA1010102XR |
DXGI_FORMAT_R10G10B10A2_UNORM | GUID_WICPixelFormat32bppRGBA1010102 |
DXGI_FORMAT_B5G5R5A1_UNORM | GUID_WICPixelFormat16bppBGRA5551 |
DXGI_FORMAT_B5G6R5_UNORM | GUID_WICPixelFormat16bppBGR565 |
DXGI_FORMAT_R32_FLOAT | GUID_WICPixelFormat32bppGrayFloat |
DXGI_FORMAT_R16_FLOAT | GUID_WICPixelFormat16bppGrayHalf |
DXGI_FORMAT_R16_UNORM | GUID_WICPixelFormat16bppGray |
DXGI_FORMAT_R8_UNORM | GUID_WICPixelFormat8bppGray |
DXGI_FORMAT_A8_UNORM | GUID_WICPixelFormat8bppAlpha |
DXGI_FORMAT_R8G8B8A8_UNORM DXGI_FORMAT_R8G8B8A8_UNORM_SRGB |
GUID_WICPixelFormat32bppRGBA |
DXGI_FORMAT_B8G8R8A8_UNORM DXGI_FORMAT_B8G8R8A8_UNORM_SRGB |
GUID_WICPixelFormat32bppBGRA |
DXGI_FORMAT_B8G8R8X8_UNORM DXGI_FORMAT_B8G8R8X8_UNORM_SRGB |
GUID_WICPixelFormat32bppBGR |
For the load functions, the metadata parameter can be nullptr as this information is also available in the returned ScratchImage.
For the metadata and loading functions, getMQR is an optional callback. If it is non-null and the WIC container codec supports a metadata query reader, then the callback is triggered. This allows an application to extract additional metadata from the file that is otherwise unused by DirectXTex.
For the saving functions, setCustomProps is an optional callback. If it is non-null, then the callback is triggered so it can set additional WIC properties such as compression methods.
This is a simple loading example. Since it only returns a single 2D image, the TexMetadata info is redundant information.
auto image = std::make_unique<ScratchImage>();
HRESULT hr = LoadFromWICFile( L"WINLOGO.BMP", WIC_FLAGS_NONE, nullptr, *image );
if ( FAILED(hr) )
// error
This is a multi-image loading example which can load an array of 2D images.
TexMetadata info;
auto image = std::make_unique<ScratchImage>();
HRESULT hr = LoadFromWICFile( L"MULTIFRAME.TIF",
WIC_FLAGS_ALL_FRAMES, &info, *image );
if ( FAILED(hr) )
// error
Here we provide an optional callback to check for the System.Photo.Orientation metadata query property:
TexMetadata info;
auto image = std::make_unique<ScratchImage>();
uint16_t orientation = 1;
HRESULT hr = LoadFromWICFile( L"Image.JPG", WIC_FLAGS_NONE, &info, *image,
[&](IWICMetadataQueryReader* reader)
{
PROPVARIANT value;
PropVariantInit( &value );
if ( SUCCEEDED(reader->GetMetadataByName( L"System.Photo.Orientation", &value ) )
&& value.vt == VT_UI2 )
{
orientation = value.uiVal;
}
PropVariantClear( &value );
} );
if ( FAILED(hr) )
// error
This is saving a simple 2D image to a specific file container. You can either use the WIC GUID directly or make use of the GetWICCodec helper. Keep in mind that WIC may convert the pixel format in the final output image, so there is an optional additional parameter you can use to request a specific storage pixel format. In this case, we want the file's pixel format to be an 8-bit per channel RGB without an alpha channel.
const Image* img = image->GetImage(0,0,0);
assert( img );
HRESULT hr = SaveToWICFile( *img, WIC_FLAGS_NONE,
GUID_ContainerFormatPng, L"NEW_IMAGE.PNG", &GUID_WICPixelFormat24bppBGR );
if ( FAILED(hr) )
// error
You can also save data directly from memory without using the intermediate ScratchImage at all. This example assumes a single 2D image is being written out since a JPG file cannot contain an image array.
Image img;
img.width = /*<width of pixel data>*/;
img.height = /*<height of pixel data>*/;
img.format = /*<a DXGI format that maps directly to a WIC supported format>*/;
img.rowPitch = /*<number of bytes in a scanline of the source data>*/;
img.slicePitch = /*<number of bytes in the entire 2D image>*/;
img.pixels = /*<pointer to pixel data>*/;
HRESULT hr = SaveToWICFile( img, WIC_FLAGS_NONE, GetWICCodec(WIC_CODEC_JPEG),
L"NEW_IMAGE.PNG" );
if ( FAILED(hr) )
// error
When writing WIC files, you can also provide a callback for setting specific encoding options.
const Image* img = image->GetImage(0,0,0);
assert( img );
HRESULT hr = SaveToWICFile( *img, WIC_FLAGS_NONE,
GUID_ContainerFormatTiff, L"NEW_IMAGE.TIF", nullptr,
[&](IPropertyBag2* props)
{
PROPBAG2 options[2] = { 0, 0 };
options[0].pstrName = const_cast<wchar_t*>(L"CompressionQuality");
options[1].pstrName = const_cast<wchar_t*>(L"TiffCompressionMethod");
VARIANT varValues[2];
varValues[0].vt = VT_R4;
varValues[0].fltVal = 0.75f;
varValues[1].vt = VT_UI1;
varValues[1].bVal = WICTiffCompressionNone;
(void)props->Write( 2, options, varValues );
});
if ( FAILED(hr) )
// error
-
WIC_FLAGS_NONE
Default flags. -
WIC_FLAGS_FORCE_RGB
By default we map many BGR formats directly to DXGI 1.1 formats. Use of this flag forces the use of DXGI 1.0 RGB formats instead for improved Direct3D 10.0/Windows Vista RTM/WDDM 1.0 driver support. -
WIC_FLAGS_NO_X2_BIAS
By defaultGUID_WICPixelFormat32bppRGBA1010102XR
is loaded asR10G10B10_XR_BIAS_A2_UNORM
. Use of this flag will force it to convert toR10G10B10A2_UNORM
instead. -
WIC_FLAGS_NO_16BPP
By default, 5:6:5 and 5:5:5:1 formats are returned as DXGI 1.2 formats. If this flag is used, the loader will expand these to R8G8B8A8 instead. -
WIC_FLAGS_ALLOW_MONO
By default, monochrome data is converted to greyscale. By using this flag, this data is loaded asR1_UNORM
which is not supported for rendering by Direct3D. -
WIC_FLAGS_ALL_FRAMES
By default, only the first frame of a multi-frame file is loaded. If this flag is provided, all frames are loaded and resized to match the size of the first image to fit the DirectXTex requirements for a 2D array.
-
WIC_FLAGS_IGNORE_SRGB
While there is no explicit 'sRGB' pixel format defined for WIC, the load function will check for known metadata tags and may returnDXGI_FORMAT_*_SRGB
formats if there are equivalents of the same size and channel configuration available. If this flag is specified, any 'sRGB' metadata is ignored instead. -
WIC_FLAGS_DEFAULT_SRGB
When there is no explicit colorspace information, the loader assumes it's a 'standard' type unless this flag is set to indicate it should useDXGI_FORMAT_*_SRGB
formats if there are equivalents. In other words, unless this flag is set or the incoming color format is explicitly_SRGB
, the reader does not set sRGB colorspace metadata. This flag is ignored if you useWIC_FLAGS_IGNORE_SRGB
. -
WIC_FLAGS_FORCE_SRGB
When writing a file, theDXGI_FORMAT_*_SRGB
formats are used to indicate the need to write with 'sRGB' metadata. If this flag is specified, 'sRGB' metadata is always written even if the input format is not explicitly anDXGI_FORMAT_*_SRGB
format. -
WIC_FLAGS_FORCE_LINEAR
When writing a file, if the type is not aDXGI_FORMAT_*_SRGB
format, then metadata for a gamma of 1.0 is written to indicate the file is in linear color space. If this flag is specified, 1.0 gamma metadata is always written even if the input format is aDXGI_FORMAT_*_SRGB
format.
Note these flags apply to the JPEG, TIFF, and PNG container file formats.
These flags control the use of dithering for image conversions. It defaults to 'no' dithering.
-
WIC_FLAGS_DITHER
WIC will use 4x4 ordered dithering. -
WIC_FLAGS_DITHER_DIFFUSION
WIC will use error-diffusion (Floyd-Steinberg dithering).
These flags control the use of interpolation modes for image conversions/resizing--WIC containers support a limited number of pixel formats, so conversions are sometimes required to write out images. It defaults to "Fant"
-
WIC_FLAGS_FILTER_POINT
Nearest-neighbor -
WIC_FLAGS_FILTER_LINEAR
- Bilinear interpolation -
WIC_FLAGS_FILTER_CUBIC
- Bicubic interpolation -
WIC_FLAGS_FILTER_FANT
- Fant which is equivalent to 'box' filteirng for down-scaling.
Note that WIC does not implement the Triangle filtering algorithm that is supported by DirectXTex's custom filtering paths.
Note that when writing out screenshots captured from Direct3D render targets, you typically do not want to write out the alpha channel. In this case, you should specify a target format of GUID_WICPixelFormat24bppBGR
, GUID_WICPixelFormat48bppBGR
, GUID_WICPixelFormat16bppBGR555
, or GUID_WICPixelFormat16bppBGR565
. GUID_WICPixelFormat96bppRGBFloat
is also an option when using WIC2 (see below).
-
JPEG-XR / HD Photo supports nearly all WIC pixel formats including floating-point for both encoding and decoding.
-
TIFF
can contain floating-point data (128bpp or 96bpp), but the WIC built-in codec can only decode such images. It always converts floating-point data to unorm when encoding. Windows 7 incorrectly handles decoding 96bppTIFF
files, which is corrected with WIC2 by returning the new formatGUID_WICPixelFormat96bppRGBFloat
-
Windows WIC codec for
.BMP
files does not support alpha channels for 16-bit files. For 32-bit files, the alpha channel is ignored by Windows 7 or earlier. The WIC2BMP
codec can read 32-bit alpha channels if using theBITMAPV5HEADER
header. DirectXTex opts into the WIC2 behavior for writing 32-bit alpha channels using the V5 header when available -
GUID_WICPixelFormat32bppRGBE
is an 8:8:8:8 format, which does not matchDXGI_FORMAT_R9G9B9E5_SHAREDEXP
. This WIC pixel format is therefore converted toGUID_WICPixelFormat128bppRGBAFloat
and returns asDXGI_FORMAT_R32G32B32A32_FLOAT
. -
Paletted WIC formats are not supported for writing by the SaveToWIC functions.
-
When writing PNG files, if the input image format is
DXGI_FORMAT_*_SRGB
, then the resulting file will have thesRGB
rendering intent chunk. Otherwise, it will not have thesRGB
chunk and instead will have an explicitgAMA
chunk of 1.0.
WIC2 is available on Windows 8 and on Windows 7 Service Pack 1 with KB 2670838 installed.
-
The WIC2 pixel format
GUID_WICPixelFormat96bppRGBFloat
loads asDXGI_FORMAT_R32G32B32_FLOAT
. Otherwise it converts this toDXGI_FORMAT_R32G32B32A32_FLOAT
. -
Conversions cases for WIC2 pixel formats
GUID_WICPixelFormat32bppRGB
,GUID_WICPixelFormat64bppRGB
, andGUID_WICPixelFormat64bppPRGBAHalf
are included. The pixel formatGUID_WICPixelFormat96bppRGBFixedPoint
is converted toDXGI_FORMAT_R32G32B32_FLOAT
rather thanDXGI_FORMAT_R32G32B32A32_FLOAT
See Windows Imaging Component and Windows 8
File access and permissions (Windows Runtime apps)
If you wish to load an image from a file that is specified by the user from a WinRT picker, you will need to copy the file locally to a temporary location before you can use LoadFromWICFile on it. This is because you either won't have file access rights to the user's file location, or the StorageFile is actually not a local file system path (i.e. it's a URL).
// Using C++/CX (/ZW) and the Parallel Patterns Library (PPL)
create_task(openPicker->PickSingleFileAsync()).then([this](StorageFile^ file)
{
if (file)
{
auto tempFolder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
create_task(file->CopyAsync( tempFolder, file->Name, NameCollisionOption::GenerateUniqueName )).then([this](StorageFile^ tempFile)
{
if ( tempFile )
{
HRESULT hr = LoadFromWICFile( ..., tempFile->Path->Data(), ... );
DX::ThrowIfFailed(hr);
}
});
});
}
For SaveToWICFile to succeed, the application must have write access to the destination path. For Windows Store apps, the file access permissions are rather restricted so you'll need to make sure you use a fully qualified path to a valid write folder. A good location to use is the app data folder:
auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
// use folder->Path->Data() as the path base
If you are going to immediately copy it to another location via StorageFolder, then use the app's temporary folder:
auto folder = Windows::Storage::ApplicationData::Current->TemporaryFolder;
// use folder->Path->Data() as the path base
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Windows 8.1
- Windows 7 Service Pack 1
- Xbox One
- Xbox Series X|S
- Windows Subsystem for Linux
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- GCC 10.5, 11.4, 12.3
- MinGW 12.2, 13.2
- CMake 3.20
DirectX Tool Kit for DirectX 11