VC/MFC怎样将位图CBitmap对象保存成为jpg格式文件?

VC/MFC怎样将位图CBitmap对象保存成为jpg格式文件?

前面几篇文章中已经实现了将 CBitmap 对象保存为 bmp 格式文件,以及将 bmp 格式转换成 jpg 格式,中间绕了一道弯,为什么不直接将 CBitmap 对象直接存为 jpg 格式呢?

 

可以借鉴下面的资料,该文中实现了先将 bmp 文件加载为 CBitmap 对象,然后使用 IJG jpeg 库函数保存为 jpg 格式文件:

VC中利用IJG库实现图片由BMP转JPG格式

http://hi.baidu.com/andyleesoft/blog/item/d6f354003fcbbe024bfb5113.html

 

我对该文中的代码进行了测试和调整,分解成两个函数:

1. 将CBitmap对象存为jpg格式文件,命名为 IJG_bmp2jpg;

1. 将bmp文件加载为CBitmap对象,然后调用第一个函数来保存为jpg格式文件。

 

/****函数功能:CBitmap存为JPG******/             
/*入口:CBitmap对象,目标文件地址,压缩质量*/
bool IJG_bmp2jpg(CBitmap& cbmp, CString Dfilepath,int quality)
{
	BITMAP bmp;


	cbmp.GetBitmap(&bmp);//获取图像信息

	if (bmp.bmBitsPixel<8)
	{
	   AfxMessageBox("不支持8位以下图像转换。");
	   return false;
	}

	byte * p = new byte[bmp.bmWidth * bmp.bmHeight*bmp.bmBitsPixel/8];//创建空间,大小=像素*每像素所占字节数

	cbmp.GetBitmapBits(bmp.bmWidth * bmp.bmHeight*bmp.bmBitsPixel/8,p);//将图像数据复制到内存

	if (bmp.bmBitsPixel==32)//32位需要特殊处理,去掉其中透明字节,并且需要改变RGB顺序
	{
  
	   for (long i=0, j=0;j<bmp.bmWidth * bmp.bmHeight*4 ;i+=3,j+=4)
	   {
		*(p+i)=*(p+j+2);
		*(p+i+1)=*(p+j+1);
		*(p+i+2)=*(p+j);
   
	   }
	}



	/************以下利用IJG库进行格式转换******************/
	struct jpeg_compress_struct jcs; /*声明JPEG压缩对象*/

	struct jpeg_error_mgr jem; /*声明错误处理器*/

	JSAMPLE *image_buffer=(JSAMPLE *)p;   /*转换的源图像缓冲区指向之前申请的内存*/

	JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */

	int row_stride; /*每行字节数*/

	jcs.err=jpeg_std_error(&jem);

	jpeg_create_compress(&jcs); /*initialize the JPEG compression object.*/

	FILE* f=fopen(Dfilepath,"wb"); /*建立JPEG文件*/

	if(f==NULL)
	{
	   AfxMessageBox("建立JPEG文件失败。");
	   fclose(f);
	   delete []p;
	   return false ;
	}

	jpeg_stdio_dest(&jcs, f); /*将目标文件与转换结果相关联*/

	jcs.image_width = bmp.bmWidth; /* image width and height, in pixels */

	jcs.image_height = bmp.bmHeight;

	jcs.input_components = (bmp.bmBitsPixel/8>=3?3:bmp.bmBitsPixel/8);   /* # of color components per pixel */

	jcs.in_color_space = JCS_RGB; /* colorspace of input image */

	jpeg_set_defaults(&jcs);

	jpeg_set_quality(&jcs, quality, TRUE /* limit to baseline-JPEG values */);

	jpeg_start_compress(&jcs, TRUE); /*开始压缩*/

	row_stride=jcs.image_width*jcs.input_components;

	while (jcs.next_scanline<jcs.image_height)
	{
	   row_pointer[0] = & image_buffer[jcs.next_scanline * row_stride];
	   (void) jpeg_write_scanlines(&jcs, row_pointer, 1);
	}

	jpeg_finish_compress(&jcs);

	fclose(f);

	jpeg_destroy_compress(&jcs);

	delete []p;

	return true;
}

/****函数功能:bmp转JPG******/             
/*入口:源文件地址,目标文件地址,压缩质量*/
bool IJG_bmp2jpg(CString Sfilepath,CString Dfilepath,int quality)
{
	CBitmap cbmp;

	HBITMAP hbitmap=(HBITMAP)::LoadImage(NULL,Sfilepath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);//位图句柄,读取外部位图

	if (hbitmap==NULL)
	{
	   AfxMessageBox("源图像读取错误");
	   return false;
	}

	cbmp.Attach(hbitmap);//将外部图像引入CBITMAP

	return IJG_bmp2jpg(cbmp, Dfilepath, quality);
}

 

调用方式如下:

				//bool IJG_bmp2jpg(CString Sfilepath,CString Dfilepath,int quality)
				IJG_bmp2jpg("clipboard.bmp", "clipboard2.jpg", 60);

				//bool IJG_bmp2jpg(CBitmap cbm,CString Dfilepath,int quality)
				IJG_bmp2jpg(*cbm, "clipboard3.jpg", 60);
 

 

你可能感兴趣的:(bitmap)