VC6怎样将bmp格式图象转换为jpg格式文件?
利用 IJG 的 jpeg 库。
关于如何使用 IJG jpeg 库,请参考前面的文章:
VC6下编译IJG库(用于读取和生成jpg格式图片文件)
函数原型:
/**************************************************************************
压缩图像到jpeg格式,如果压缩前的图像不是24位图,则强行转换为24位图后压缩
**************************************************************************/
// strSourceFileName - 原始bmp文件名
// strDestFileName - 想要生成的jpg文件名
// quality - 图象质量 1-100的数字,比如 60
void bmptojpg24x(const char *strSourceFileName, const char *strDestFileName, int quality);
先列出调用方式:
// 将生成的 bmp 转换成 jpg 格式
bmptojpg24x("clipboard.bmp", "clipboard.jpg", 60);
// 压缩比率:60%
// 575* 865 bmp 1,989,568 字节 jpg 46,364 字节 大约 50毫秒
// 1000*1498 bmp 5,992,068 字节 jpg 225,699 字节 大约200毫秒
// 1335*2000 bmp 10,680,068 字节 jpg 205,151 字节 大约300毫秒
下面的调用代码加入了执行时间计算:
// 下面的代码加上了转换所需时间的计算
// GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD。
DWORD t0 = ::GetTickCount();
bmptojpg24x("clipboard.bmp", "clipboard.jpg", 60);
DWORD t1 = ::GetTickCount();
char tstr[32]; sprintf(tstr, "bmptojpg24 use %d ms", t1 - t0); MessageBox(tstr);
下面是完整的原代码:
/**************************************************************************
压缩图像到jpeg格式,如果压缩前的图像不是24位图,则强行转换为24位图后压缩
**************************************************************************/
// strSourceFileName - 原始bmp文件名
// strDestFileName - 想要生成的jpg文件名
// quality - 图象质量 1-100的数字,比如 60
void bmptojpg24x(const char *strSourceFileName, const char *strDestFileName, int quality)
{
BITMAPFILEHEADER bfh; // bmp文件头
BITMAPINFOHEADER bih; // bmp头信息
RGBQUAD rq[256]; // 调色板
int i=0;
BYTE *data= NULL;//new BYTE[bih.biWidth*bih.biHeight];
BYTE *pData24 = NULL;//new BYTE[bih.biWidth*bih.biHeight];
int nComponent = 0;
// 打开图像文件
FILE *f = fopen(strSourceFileName,"rb");
if (f==NULL)
{
TRACE("Open file error!\n");
::MessageBox(0, "Open file error!", "bmptojpg24", MB_OK);
return;
}
// 读取文件头
fread(&bfh,sizeof(bfh),1,f);
// 读取图像信息
fread(&bih,sizeof(bih),1,f);
// 为了简单,在本例中,只演示8位索引图像
switch (bih.biBitCount)
{
case 8:
if (bfh.bfOffBits-1024<54)
{
fclose(f);
return;
}
data= new BYTE[bih.biWidth*bih.biHeight];
pData24 = new BYTE[bih.biWidth*bih.biHeight*3];
// 定位调色板,并读取调色板
fseek(f,bfh.bfOffBits-1024,SEEK_SET);
fread(rq,sizeof(RGBQUAD),256,f);
// 读取位图
fread(data,bih.biWidth*bih.biHeight,1,f);
fclose(f);
nComponent = 3;
for (i=0;i<bih.biWidth * bih.biHeight ;i++)
{
pData24[i*3] = rq[data[i]].rgbRed;
pData24[i*3+1] = rq[data[i]].rgbGreen;
pData24[i*3+2] = rq[data[i]].rgbBlue;
}
break;
case 24:
{
data= new BYTE[bih.biWidth*bih.biHeight*3];
pData24 = new BYTE[bih.biWidth*bih.biHeight*3];
fseek(f,bfh.bfOffBits,SEEK_SET);
fread(data,bih.biWidth*bih.biHeight*3,1,f);
fclose(f);
for (i = 0;i<bih.biWidth*bih.biHeight;i++)
{
pData24[i*3] = data[i*3+2];
pData24[i*3+1] = data[i*3+1];
pData24[i*3+2] = data[i*3];
}
nComponent = 3;
break;
}
case 32:
{
data= new BYTE[bih.biWidth*bih.biHeight*4];
pData24 = new BYTE[bih.biWidth*bih.biHeight*3];
fseek(f,bfh.bfOffBits,SEEK_SET);
fread(data,bih.biWidth*bih.biHeight*4,1,f);
fclose(f);
for (i = 0;i<bih.biWidth*bih.biHeight;i++)
{
pData24[i*3] = data[i*4+2];
pData24[i*3+1] = data[i*4+1];
pData24[i*3+2] = data[i*4];
}
nComponent = 3;
break;
}
default:
{
char tmpbuf[32];
sprintf(tmpbuf, "bih.biBitCount=%d not supported", bih.biBitCount);
::MessageBox(0, tmpbuf, "bmptojpg24", MB_OK);
fclose(f);
return;
}
}
// 以上图像读取完毕
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);
f=fopen(strDestFileName,"wb");
if (f==NULL)
{
delete [] data;
//delete [] pDataConv;
return;
}
jpeg_stdio_dest(&jcs, f);
jcs.image_width = bih.biWidth; // 为图的宽和高,单位为像素
jcs.image_height = bih.biHeight;
jcs.input_components = nComponent; // 1,表示灰度图, 如果是彩色位图,则为3
if (nComponent==1)
jcs.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像
else
jcs.in_color_space = JCS_RGB;
jpeg_set_defaults(&jcs);
//jpeg_set_quality (&jcs, 60, true);
jpeg_set_quality (&jcs, quality, true);
jpeg_start_compress(&jcs, TRUE);
JSAMPROW row_pointer[1]; // 一行位图
int row_stride; // 每一行的字节数
row_stride = jcs.image_width*nComponent; // 如果不是索引图,此处需要乘以3
// 对每一行进行压缩
while (jcs.next_scanline < jcs.image_height) {
row_pointer[0] = & pData24[(jcs.image_height-jcs.next_scanline-1) * row_stride];
jpeg_write_scanlines(&jcs, row_pointer, 1);
}
jpeg_finish_compress(&jcs);
jpeg_destroy_compress(&jcs);
fclose(f);
delete [] data;
delete [] pData24;
//::MessageBox(0, "ok", "bmptojpg24", MB_OK);
}
本文所附原代码参考了下面的资料:
利用IJG JPEG Library压缩图像为jpg格式 http://www.vckbase.com/document/viewdoc/?id=1790
作了如下改进:
1. 增加了对32位图象的处理,只取 RGB分量,忽略 alpha值;
2. 增加图象质量参数 quality ,可以指定图片压缩 比率,更方便调用;
3. 少量调试信息 MessageBox 。
更多参考资料:
1. VC2005 使用IJG读写JPEG格式文件
http://iysm.net/?p=7
2. IJG是什么,有哪些优点 IJG VS IJL
http://www.cr173.com/html/11042_1.html
3. VC中利用IJG库实现图片由BMP转JPG格式
http://hi.baidu.com/andyleesoft/blog/item/d6f354003fcbbe024bfb5113.html
分享到:
相关推荐
这可以通过OpenCV的imread函数完成,它可以读取常见的图像文件格式,如.jpg、.png或.bmp。然后,我们可以使用imshow函数将图像显示在窗口中,以便于观察和调试。 在VC2005中,开发图像处理程序时,开发者需要了解...
代码可能会演示如何处理不同的图像格式(如.jpg、.png、.bmp)。 2. **图像滤波**:包括均值滤波、高斯滤波、中值滤波等,用于消除噪声或平滑图像。例如,OpenCV中的`blur`、`GaussianBlur`和`medianBlur`函数。 3...
要将JPEG图像另存为其他格式,如位图(BMP),可以使用CImage的Save函数,指定保存的格式和路径: ```cpp if (!image.Save("output.bmp", NULL, BI_RGB)) { // 处理保存失败的情况 } ``` 需要注意的是,JPEG是...
6. **学习与实践**:通过这些源代码,学习者可以了解图像处理算法的实现细节,如如何读取和写入图像文件(通常使用bmp、jpg、png格式),如何在内存中表示和操作像素,以及如何将算法应用于实际图像。 7. **调试与...
a2r103.zip 转换ANSI 屏幕到RIP格式(17KB)<END><br>47,show204.zip GIF/PCX/JPEG 观察器(252KB)<END><br>48,bmp.zip 操纵位图的开发包(78KB)<END><br>49,draw_in.zip 在状态条里显现图(29KB)<END><br>50...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...
内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...