`
coding1688
  • 浏览: 236840 次
  • 来自: 上海
社区版块
存档分类
最新评论

VC6怎样将bmp格式图象转换为jpg格式文件?

 
阅读更多

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

 

 

1
1
分享到:
评论

相关推荐

    VC图象处理(VS2005)

    这可以通过OpenCV的imread函数完成,它可以读取常见的图像文件格式,如.jpg、.png或.bmp。然后,我们可以使用imshow函数将图像显示在窗口中,以便于观察和调试。 在VC2005中,开发图像处理程序时,开发者需要了解...

    VC图象处理例子及其代码

    代码可能会演示如何处理不同的图像格式(如.jpg、.png、.bmp)。 2. **图像滤波**:包括均值滤波、高斯滤波、中值滤波等,用于消除噪声或平滑图像。例如,OpenCV中的`blur`、`GaussianBlur`和`medianBlur`函数。 3...

    数字图像处理实验4 VC/VS MFC 编写JPEG图象读/写程序

    要将JPEG图像另存为其他格式,如位图(BMP),可以使用CImage的Save函数,指定保存的格式和路径: ```cpp if (!image.Save("output.bmp", NULL, BI_RGB)) { // 处理保存失败的情况 } ``` 需要注意的是,JPEG是...

    图象处理源代码集(VC++实现)

    6. **学习与实践**:通过这些源代码,学习者可以了解图像处理算法的实现细节,如如何读取和写入图像文件(通常使用bmp、jpg、png格式),如何在内存中表示和操作像素,以及如何将算法应用于实际图像。 7. **调试与...

    Visual C++ 编程资源大全(源码 图形)

    a2r103.zip 转换ANSI 屏幕到RIP格式(17KB)&lt;END&gt;&lt;br&gt;47,show204.zip GIF/PCX/JPEG 观察器(252KB)&lt;END&gt;&lt;br&gt;48,bmp.zip 操纵位图的开发包(78KB)&lt;END&gt;&lt;br&gt;49,draw_in.zip 在状态条里显现图(29KB)&lt;END&gt;&lt;br&gt;50...

    vc++ 应用源码包_6

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 开发实例源码包

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_1

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_2

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_3

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    vc++ 应用源码包_5

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

Global site tag (gtag.js) - Google Analytics