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; extern IStream *pMyJpeg;
if (Gdiplus::Ok == imageToImage(pSomeImg, pMyJpeg, L"image/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.