最近在学习GDI+,刚好学习到了图片的编码和解码部分。bmp格式的图片没有进行压缩,所以图片所占内存比较大,而PNG图片经过压缩后体积较小,所以我想进行下图片格式转换。刚好在微软GDI+的文档中有这么一个实例,我将他贴出来,并展现转换后两个图片所占空间的大小。
#include <windows.h>
#include <ObjIdl.h>
#include <iostream>
#include <gdiplus.h>
using namespace std;
#pragma comment(lib, "Gdiplus.lib")
using namespace Gdiplus;
int GetEncoderClsid(const WCHAR* format, CLSID* pClisid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j)
{
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
{
*pClisid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
int main()
{
//初始化GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput,NULL);
CLSID encoderClsid;
Status stat;
Image* image = new Image(L"C:\\Users\\DreamXY\\Desktop\\4.bmp");
//Get the CLSID of the PNG encoder
GetEncoderClsid(L"image/png", &encoderClsid);
stat = image->Save(L"4.png", &encoderClsid, NULL);
if (stat == Ok)
cout << "4.png was saved successfully" << endl;
else
cout << "failure: stat = %d " << stat;
delete image;
GdiplusShutdown(gdiplusToken);
return 0;
}
上面程序的原理是:首先获取你想要转换成哪个图像格式的编码器ID(我是将其理解为这个),当然这个编码器必须在windows上有的,如果没有就返回-1。找到对应图片格式的编码器ID,之后用
Image类中的Save方法将其保存到其他的图片格式。
需要注意的是,单纯的修改后缀名是没有用的。比如将程序中4.bmp改为4.png,这个操作是没有任何效果的,因为图片内的数据排列格式并没有改变,也就是说并没有对图片内部进行重新编码。
转换后图片大小对比:
首先是原图像4.bmp
这是转换后的4.png图像
由上面两图可以看出,转换成PNG格式图片后,图片的大小明显变小了。