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.