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);
分享到:
相关推荐
- 位图使用完毕后,记得使用CDC的SelectObject()函数将原始的DC选择回来,然后使用CBitmap对象的DeleteObject()函数释放位图资源。 在“DIBDisplay”示例中,可能涉及到了DIB(Device Independent Bitmap)的处理...
MFC提供了CBitmap类来操作位图,包括加载、显示和绘图。LoadBitmap()函数可以从资源中加载位图,CreateBitmap()和CreateDIBitmap()可用于创建位图对象。位图可以在设备上下文中通过BitBlt()函数进行复制、剪切或旋转...
在这个问题中,我们专注于如何利用MFC中的CBitmap类以及CImage类将图像数据保存到文件。以下是关于这一主题的详细解释。 首先,`CBitmap`是MFC提供的一个类,它封装了Windows API中的`BITMAP`结构,用于处理位图...
这个实例“VC MFC界面编程实例之位图按钮”旨在教授如何在MFC应用中集成位图按钮,为用户提供更加美观且直观的交互体验。位图按钮是指将普通按钮替换为具有自定义图像的按钮,使得UI设计更加丰富多彩。 首先,我们...
此外,为了提高性能,可以考虑使用位图刷(CBitmap brush)缓存PNG图像,而不是每次OnPaint()都重新加载。 总之,通过集成GDI+库,自定义控件并利用其透明特性,我们能够在MFC对话框的按钮上成功加载并显示PNG图片...
在这个场景中,“窗口DC保存至BMP,JPG”是指利用窗口设备上下文(Device Context,简称DC)来捕获窗口的内容,并将其保存为位图(Bitmap,BMP)或联合图像文件格式(JPEG,JPG)。 1. **窗口DC(Device Context)*...
以上就是如何在VC MFC程序中加载和显示位图的基本步骤。请注意,这只是一个基础示例,实际应用中可能需要考虑更多的细节,如错误处理、位图缩放等。希望这个教程能帮助你理解MFC中显示位图的原理和方法。
《VC++ MFC实现画图程序详解》 在软件开发领域,VC++是Microsoft公司推出的一种集成开发环境,它基于C++编程语言,而MFC(Microsoft Foundation Classes)是微软提供的一个类库,用于简化Windows应用程序的开发。本...
在给定的“【VC_MFC_自绘装载动位图的按钮】BmpButton.rar”资源中,我们关注的是如何在MFC的对话框中创建一个自绘的按钮,这个按钮不仅具有文本,还能显示动态的位图图像,从而提升应用的视觉吸引力。 在MFC中,...
在本文中,我们将深入探讨如何使用Microsoft Foundation Classes (MFC) 在VC6.0环境下进行数字图像处理,特别是关于BMP格式图片的打开与保存。MFC是Microsoft为Windows应用程序开发提供的一组C++类库,它简化了...
总结,实现MFC VC界面编程中的特色位图菜单需要理解MFC的菜单系统、位图处理以及自定义绘制技术。通过创建自定义菜单类并重写关键的绘图函数,我们可以实现各种风格的位图菜单,如Office XP样式,提升应用的用户体验...
在MFC中,保存图形通常涉及到将图形数据保存到文件,如BMP、JPEG或PNG等图像格式。可以使用CFile类来处理文件I/O,然后使用位图对象(CBitmap)和内存设备上下文(CMemDC)来实现。以下是一个简单的例子,将窗口内容...
在VC++ 6.0开发环境中,利用MFC(Microsoft Foundation Classes)库,可以实现对多种图像格式,如BMP、JPG、GIF、TIFF和RAW的支持。以下将详细讲解如何在VC++ 6.0中进行这些操作。 首先,你需要了解不同图像格式的...
首先,你需要包含`#include <gdiplus.h>`,然后在代码中初始化GDI+,加载CBitmap到GDI+的Bitmap对象,最后调用Save函数保存到文件。以下是一个简化的示例: ``` Gdiplus::Graphics graphics(hdc); // 获取绘图环境...
4. 使用`CDC`和`CBitmap`对象将图像绘制到内存DC上。 5. 调用`CBitmap::SaveBitmapFile`或`CImage::Save`方法将位图保存为图片文件(如JPEG、PNG等)。 ### 5. 错误处理与资源释放 在实现过程中,要注意处理可能...
5. **保存位图到文件**:保存位图到磁盘文件通常涉及到将位图的数据写入特定格式的文件,如BMP、JPEG或PNG。在VC++中,这通常通过调用`CDC::SaveBitmapFile`或使用GDI+的`Bitmap::Save`函数来完成。对于BMP格式,...
在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 库在Visual C++ (VC++) 中开发一个位图查看器。MFC 是微软提供的一套C++ 类库,它封装了Windows API,简化了Windows 程序的设计与实现。 首先,...
"VC通过路径加载位图源码例子"是一个典型的编程任务,涉及到Windows API函数和MFC(Microsoft Foundation Classes)库的使用。下面将详细介绍这个过程中的关键知识点。 1. **Windows API**: Windows API提供了...
在这个函数中,使用`CDC`类(设备上下文类)的`SelectObject`方法选择我们的`CBitmap`对象,然后使用`StretchBlt`或`BitBlt`函数将位图绘制到客户区。例如: ```cpp CDC* pDC = GetDC(); CRect rect; ...
BMP是一种无损的图形文件格式,广泛用于存储图像数据。本篇文章将深入探讨如何在VC++ 6.0 MFC(Microsoft Foundation Classes)框架下,解析和显示不同位深度(8位、16位、24位和32位)的BMP图像。 首先,理解BMP...