C++ 图片格式转化和压缩

时间:2023-03-09 19:11:49
C++ 图片格式转化和压缩

在做人脸识别底库图片导入的时候,需要支持主流的图片的格式,如jpeg、bmp、png等格式。所以需要对图片进行格式转化。图片过大的话,还有进行缩放等。本文介绍的是利用cximage开源库,来进行对图片进行格式转化和压缩。

使用cximage库的好处是支持各种平台,如windows、linux系统上都可以使用。

1、首先从开源网站上下载cximage库。

一般下载下来的cximage库支持大部分的图片格式,可以根据项目要求,进行裁剪,比如支持jpeg、bmp和png三种格式的话,可以裁剪到很多库。

修改的头文件:ximacfg.h, 不需要支持的图片格式,可以直接改成0

C++ 图片格式转化和压缩

2、本次用到的函数介绍:

1)、bool Load(const TCHAR* filename, DWORD imagetype=0);

CxImage(const TCHAR * filename, DWORD imagetype);

可以直接传入一个路径,直接加载

2)CxImage(BYTE * buffer, DWORD size, DWORD imagetype);

也可以通过上面的构造函数,直接传入图片的内存数据和大小

3)bool IsValid() const;

检查图片是否正确初始化

4)bool Resample(long newx, long newy, int mode = 1, CxImage* iDst = NULL);

自定义图片大小(缩放)

3、下面的一段代码是把bmp、png格式的图片转成jpeg格式,如果图片过大,并进行缩放。

※ cximage转化后的jpeg格式是420采样的。

 // 图片压缩和格式转化
int CompressPicure(char * inData, int inSize, char * outData, int & outSize)
{
int picType = getPictureType((unsigned char *)inData, inSize);
int iTmpOutSize = ;
if (picType == -)
{
printf("picType is not valid.\n");
return -;
}
CxImage image((BYTE *)inData, inSize, picType);
if (!image.IsValid())
{
printf("image is not valid.\n");
return -;
} if (image.GetWidth() > || image.GetHeight() > )
{
//缩放一下
int rewith = (image.GetWidth() > ? : image.GetWidth());
int height = (image.GetHeight() > ? : image.GetHeight());
image.Resample(rewith, height, );
} image.SetJpegQuality(JPEG_QUALITY_DEFAULT); CxMemFile memfile;
memfile.Open();
image.Encode(&memfile, CXIMAGE_FORMAT_JPG);
BYTE *pImageBuf = memfile.GetBuffer();
iTmpOutSize = memfile.Size();
if (iTmpOutSize <= outSize)
{
outSize = iTmpOutSize;
memcpy(outData, pImageBuf, outSize);
}
else
{
outSize = ;
}
image.FreeMemory(pImageBuf);
memfile.Close();
return ;
}

获取图片格式 ,只支持png、bmp和jpeg。

int getPictureType(unsigned char * data, int isize)
{
if (data == NULL || isize < )
{
return -;
} // JPEG (jpg),文件头:FFD8FF
if (data[] == 0xFF && data[] == 0xD8 && data[] == 0xFF)
{
return CXIMAGE_FORMAT_JPG;
}
// PNG (png),文件头:89504E47
else if (data[] == 0x89 && data[] == 0x50
&& data[] == 0x4E && data[] == 0x47)
{
return CXIMAGE_FORMAT_PNG;
}
// Windows Bitmap (bmp),文件头:424D
else if (data[] == 0x42 && data[] == 0x4D)
{
return CXIMAGE_FORMAT_BMP;
}
else
{
return -;
}
}