在做人臉識別底庫圖片導入的時候,需要支持主流的圖片的格式,如jpeg、bmp、png等格式。所以需要對圖片進行格式轉化。圖片過大的話,還有進行縮放等。本文介紹的是利用cximage開源庫,來進行對圖片進行格式轉化和壓縮。
使用cximage庫的好處是支持各種平台,如windows、linux系統上都可以使用。
1、首先從開源網站上下載cximage庫。
一般下載下來的cximage庫支持大部分的圖片格式,可以根據項目要求,進行裁剪,比如支持jpeg、bmp和png三種格式的話,可以裁剪到很多庫。
修改的頭文件:ximacfg.h, 不需要支持的圖片格式,可以直接改成0
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采樣的。
1 // 圖片壓縮和格式轉化 2 int CompressPicure(char * inData, int inSize, char * outData, int & outSize) 3 { 4 int picType = getPictureType((unsigned char *)inData, inSize); 5 int iTmpOutSize = 0; 6 if (picType == -1) 7 { 8 printf("picType is not valid.\n"); 9 return -1; 10 } 11 CxImage image((BYTE *)inData, inSize, picType); 12 if (!image.IsValid()) 13 { 14 printf("image is not valid.\n"); 15 return -1; 16 } 17 18 if (image.GetWidth() > 400 || image.GetHeight() > 300) 19 { 20 //縮放一下 21 int rewith = (image.GetWidth() > 400 ? 400 : image.GetWidth()); 22 int height = (image.GetHeight() > 300 ? 300 : image.GetHeight()); 23 image.Resample(rewith, height, 1); 24 } 25 26 image.SetJpegQuality(JPEG_QUALITY_DEFAULT); 27 28 CxMemFile memfile; 29 memfile.Open(); 30 image.Encode(&memfile, CXIMAGE_FORMAT_JPG); 31 BYTE *pImageBuf = memfile.GetBuffer(); 32 iTmpOutSize = memfile.Size(); 33 if (iTmpOutSize <= outSize) 34 { 35 outSize = iTmpOutSize; 36 memcpy(outData, pImageBuf, outSize); 37 } 38 else 39 { 40 outSize = 0; 41 } 42 image.FreeMemory(pImageBuf); 43 memfile.Close(); 44 return 0; 45 }
獲取圖片格式 ,只支持png、bmp和jpeg。
int getPictureType(unsigned char * data, int isize) { if (data == NULL || isize < 4) { return -1; } // JPEG (jpg),文件頭:FFD8FF if (data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF) { return CXIMAGE_FORMAT_JPG; } // PNG (png),文件頭:89504E47 else if (data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) { return CXIMAGE_FORMAT_PNG; } // Windows Bitmap (bmp),文件頭:424D else if (data[0] == 0x42 && data[1] == 0x4D) { return CXIMAGE_FORMAT_BMP; } else { return -1; } }