Windows Imaging Component

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

Windows Imaging Component (WIC in short) is the new platform to
load, save and convert images between various image formats, including
the latest HD Photo format designed and aggressively pushed by
Microsoft, to be the JPEG2000 replacement. Unlike JPEG2000 which is
plagued by various patents issues, HD Photo standard is a open standard
which is free for all to use. HD Photo has a compression rate and
picture qualities better than JPEG and JPEG2000. Windows Imaging
Component is also a platform for programmers to write their own image
codecs for their own image format or RAW images from digital cameras.
The standard codecs, which are provided in the Windows Imaging
Component, are more secure than those provided by GDI+. WIC only
provides ways to load and convert and save images; To display an image
loaded by WIC, you either use Device Independent Bitmaps(DIB) or GDI+.
The sample code provided by Microsoft uses DIBs which are difficult to
use. For this article, we will use GDI+. The advantages of using GDI+
is that you can do drawing or further image processing on the GDI+
image.

Some Pictures

Since no web browser supports displaying of HD photos yet. I have put up some JPEG pictures converted from HD Photos format. Note: there are unavoidable image quality degradation in the conversion because compression is involved twice.

Photo Notes:This is the front view of new office building which my company just moved in barely 2 weeks ago.

Photo Notes:I have the paranormal view, from my desk, which my colleagues envy. This is the left view of my window. The building with the red roof is the train station which I walk 15 minutes from there to office everyday.

Photo Notes:This is the right view of my window where you could see my office is just beside a mega-mart where there are many good restaurants and shops.

Building the Sample Code

Windows Vista and Windows XP SP3 comes with WIC. To get WIC to run my sample projects on your Windows XP (non SP3) PC, you either install Microsoft .NET Framework 3.0 or install the Windows Imaging Component(32 bit) or Windows Imaging Component(64 bit). To get sample code on how to program WIC using .NET or WIC COM interfaces, you can download Windows Imaging Component Sample Source and tools.

To build the sample code presented in this article, you need to download and install Windows SDK update for Vista. Because the wincodec.idl and wincodecsdk.idl
in the sample projects refers to files on my development PC, you need
to remove them from the projects and add them in again with their
locations in the Windows SDK on your development PC.

Using the Code

To load the WIC images into GDI+, we use the LoadHdPhotos class and its static member function, GetImage().

class LoadHdPhotos
{
public:

static bool GetImage(
    CComPtr<IWICImagingFactory> imagingFactory,
    const std::wstring& szFile,
    Gdiplus::Bitmap*& pbmp,
    Gdiplus::Bitmap*& pImageThumb );
};

To use the GetImage() function, you need to create the IWICImagingFactory object first. I chose not to encapsulate this factory object into LoadHdPhotos is because this factory object is meant to be created once and used multiple times when loading and/or saving images.

Let us see some example code of using this function.

m_ImagingFactory.CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER );

if(m_ImagingFactory)
{
    using namespace Gdiplus;
    Bitmap* pImageThumb = NULL;
    bool bRet = LoadHdPhotos::GetImage(
        m_ImagingFactory,
        L"E:\\Media\\MyImage.hdp",
        m_pbmp,
        pImageThumb );

    if( bRet && m_pbmp!= NULL )
    {
        // after getting the GDI+ image, display it or do further processing.
        CClientDC dc(this);
        Graphics graphics(dc.GetSafeHdc());
        graphics.DrawImage(m_pbmp,0,0,m_pbmp->GetWidth(),m_pbmp->GetHeight());

    }
}

After your further processing, you may wish to save the resultant image. To do this you will use the SaveHdPhotos class. The SaveHdPhotos class simply wraps the CImageTransencoder class from the WICExplorer sample code from the WIC sample tools.

SaveHdPhotos save;
save.SetLossless(false);
save.SetCompressionQuality(0.8f);
save.SetImageQuality(0.8f);

save.SetDpi( (double)m_pbmp->GetHorizontalResolution(),
    (double)m_pbmp->GetVerticalResolution() );
save.SetPixelFormat( GUID_WICPixelFormat24bppBGR );

save.Begin(
    L"E:\\Media\\MyImage2.hdp",
    m_ImagingFactory);

if( m_pbmp && pImageThumb )
    save.AddFrame( m_pbmp, pImageThumb );
else if( m_pbmp )
    save.AddFrame( m_pbmp, NULL );

save.End();

Convert Between Images

To convert between different image formats, do not use LoadHdPhotos and SaveHdPhotos because they use GDI+, and “the middle man,” which is a highly inefficient way to convert images. You can use WIC to do it.

class ConvImage
{
public:
    bool ConvertImage(
        CComPtr<IWICImagingFactory> imagingFactory,
        const std::wstring& szSrcFile,
        const std::wstring& szDestFile );
};

if(m_ImagingFactory)
{
    // saving
    ConvImage convImage;

    convImage.SetLossless(false);
    convImage.SetCompressionQuality(0.8f);
    convImage.SetImageQuality(0.8f);

    convImage.ConvertImage(
        m_ImagingFactory,
        L"D:\\Media\\lyf_39.jpg",
        L"D:\\Media\\lyf_39.hdp" );
}

Sample Code

I have included 2 sample projects to demostrate the classes I wrote.
The DateStampImage project opens an image and adds a current date/time
stamp at the top left corner of the image, and you can save it in any
format you want. ImageConvertor is a simple project to convert between
different image formats, using WIC.

References

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read