These functions use the Windows Imaging Componet (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.

GetMetadataFromWICMemory
GetMetadataFromWICFile
Returns the TexMetadata from a WIC-supported bitmap file.

HRESULT GetMetadataFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource,
    _In_ size_t size, _In_ DWORD flags,
    _Out_ TexMetadata& metadata );

HRESULT GetMetadataFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
    _Out_ TexMetadata& metadata );

LoadFromWICMemory
LoadFromWICFile
Loads a WIC-supported bitmap file.

HRESULT LoadFromWICMemory( _In_reads_bytes_(size) LPCVOID pSource,
    _In_ size_t size, _In_ DWORD flags,
    _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );

HRESULT LoadFromWICFile( _In_z_ LPCWSTR szFile, _In_ DWORD flags,
    _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );

SaveToWICMemory
SaveToWICFile
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( _In_ const Image& image, _In_ DWORD flags,
    _In_ REFGUID guidContainerFormat,
    _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr,
    _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );

HRESULT SaveToWICMemory( _In_count_(nimages) const Image* images,
    _In_ size_t nimages, _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
    _Out_ Blob& blob, _In_opt_ const GUID* targetFormat = nullptr,
    _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );

HRESULT SaveToWICFile( _In_ const Image& image, _In_ DWORD flags,
    _In_ REFGUID guidContainerFormat,
    _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr,
    _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );

HRESULT SaveToWICFile( _In_count_(nimages) const Image* images, _In_ size_t nimages,
    _In_ DWORD flags, _In_ REFGUID guidContainerFormat,
    _In_z_ LPCWSTR szFile, _In_opt_ const GUID* targetFormat = nullptr,
    _In_opt_ std::function<void(IPropertyBag2*)> setCustomProps = nullptr );

Examples

This is a simple loading example. Since it only returns a single 2D image, the TexMetadata info is redundant information.

unique_ptr<ScratchImage> image ( new 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;
unique_ptr<ScratchImage> image ( new ScratchImage );
HRESULT hr = LoadFromDDSFile( L"MULTIFRAME.TIF", WIC_FLAGS_ALL_FRAMES, &info, *image );
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 = L"CompressionQuality";
        options[1].pstrName = 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

Related Flags


These flags control the use of dithering for image conversions. It defaults to 'no' dithering.
These flags control the use of interpolation modes for image conversions/resizing. It defaults to "Fant"

Release Notes

WIC2

WIC2 is available on Windows 8 and on Windows 7 Service Pack 1 with KB 2670838 installed.
http://support.microsoft.com/kb/2670838

Windows Store apps

Load

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).

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);
            }
        });
    });

http://msdn.microsoft.com/en-us/library/windows/apps/hh758319.aspx

Save

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

http://msdn.microsoft.com/en-us/library/windows/apps/hh967755.aspx