Converting between different image formats (using GDI+)
Shows how to convert between different image formats by using GDI+
Given an input stream of some type of image, the following function converts that image into another type of image given the destination format. The destination format should be a proper mime-type such as
"image/jpeg"
, "image/png"
.
Gdiplus::Status imageToImage( IStream *pStreamIn, IStream *pStreamOut, BSTR wszOutputMimeType) { namespace G = Gdiplus; G::Status status = G::Ok; G::Image imageSrc(pStreamIn); status = imageSrc.GetLastStatus(); if (G::Ok != status) { return status; } UINT numEncoders = 0; UINT sizeEncodersInBytes = 0; status = G::GetImageEncodersSize(&numEncoders, &sizeEncodersInBytes); if (status != G::Ok) { return status; } G::ImageCodecInfo *pImageCodecInfo = (G::ImageCodecInfo *) malloc(sizeEncodersInBytes); status = G::GetImageEncoders( numEncoders, sizeEncodersInBytes, pImageCodecInfo); if (status != G::Ok) { return status; } CLSID clsidOut; status = G::UnknownImageFormat; for (UINT j = 0; j < numEncoders; j ++) { if (0 == wcscmp(pImageCodecInfo[j].MimeType, wszOutputMimeType)) { clsidOut = pImageCodecInfo[j].Clsid; status = G::Ok; break; } } free(pImageCodecInfo); if (status != G::Ok) { return status; } return imageSrc.Save(pStreamOut, &clsidOut); }It can be used like so:
extern IStream *pSomeImg; // source image format is not important extern IStream *pMyJpeg; if (Gdiplus::Ok == imageToImage(pSomeImg, pMyJpeg, L"image/jpeg")) { // pMyJpeg holds the converted jpeg. }If there is a need to put/retrieve data into/from
IStream
in byte-array format (such as char*
), it can by done by using CreateStreamOnHGlobal
, GlobalAlloc
, GlobalLock
Win32 API functions. See this tip for more details.
Note: List of supported formats: BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF.