从网上搜到一个Bmp<->jpg 图片相互转换的程序,细看来感觉怪异:
其大致思路为
IplImage *src=cvLoadImage(原图),然后直接修改文件扩展名,如将.jpg 改为.bmp ,然后再 cvSaveImage(改过扩展名后的文件,原图),仅仅是修改一下后缀就可以将这两种文件格式相互转换?不需要考虑压缩编解码的问题?这样与在windows中直接修改扩展名又有何区别?
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
int main(int argc, char *argv[])
{
system("dir /b jpg > jpglist.txt");
ifstream jpglist("jpglist.txt");
vector<string> jpgName;
string buf;
while(jpglist)
{
if(getline(jpglist,buf))
{
jpgName.push_back(buf);
}
}
jpglist.close();
for(string::size_type i=0;i<jpgName.size();i++)
{
string save_dir="bmp/";
string open_dir="jpg/";
string filename=jpgName[i];
string file_no_ext="";
for(int j=0;j<jpgName[i].length()-4;j++)
{
file_no_ext+=filename[j];
}
file_no_ext.append(".bmp");
IplImage *src=cvLoadImage(open_dir.append(jpgName[i]).c_str());
if(!src)
{
cout<<"can not load the image : "<<jpgName[i]<<endl;
break;
}
cout<<"processing "<<jpgName[i]<<endl;
cvSaveImage(save_dir.append(file_no_ext).c_str(),src);
cvReleaseImage(&src);
src=NULL;
}
system("PAUSE");
return EXIT_SUCCESS;
}
基础知识:
24位bmp是公认最好的图片存储格式,存储了图片所有的信息,每个像素用24位二进制来存储该像素点的图像信息,即3字节。(16位bmp 则是24位的2/3)。如我的图片1.jpg 为1280 pixels *800 pixels,则转换为bmp后,图像大小为1280*800*3 B = 2.92MB(win7下文件大小),原图大小为243KB;
使用上面转换程序,由1.bmp 转换为1.jpg时,图像大小变为327KB。
这中间所经历的变换,应该是由cvSaveImage() 时检测文件后缀时进行了编码器的自适应。(多好用的blackbox 啊)
原理类似于保存视频文件
cvWriteFrame( CvVideoWriter* writer, const IplImage* image )中的 CvVideoWriter
CVAPI(CvVideoWriter*) cvCreateVideoWriter( const char* filename, int fourcc,
double fps, CvSize frame_size,
int is_color CV_DEFAULT(1))
P.S. 当然,如果你仅仅是在windows下修改一下文件后缀,文件大小是不会变的。
dir 的目录范围
dir /b *jpg = dir *jpg /b