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.
Building the Sample Code
Windows Vista comes with WIC. To get WIC to run my sample projects on your Windows XP PC, you either install Microsoft .NET Framework 3.0 or install the Windows Imaging Component. 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 )
{
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+ 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)
{
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.
History
May 9th, First release
May 13th, Overloaded a Begin()
function in SaveHdPhotos
class to detect which file format to save automatically, according to the file extension.