在VC下显示JPEG、GIF格式图像的一种简便方法

在VC下显示JPEG、GIF格式图像的一种简便方法,第1张

在VC下显示JPEG、GIF格式图像的一种简便方法,第2张

一.导言

JPEG图像压缩标准自然是一种有损图像压缩标准。但是由于人类视觉的不敏感,压缩后的图像质量基本没有变化,并且以其高压缩率得到了广泛的认可。GIF格式虽然只支持256色,但是对于颜色较少的图像有很高的压缩率,甚至超过JPEG标准,得到了广泛的认可。但是作为很多程序员的重要开发工具——微软Visual C++ 6.0的MFC库,只对BMP位图文件有很好的支持,没有任何压缩,可以读取、显示、存储,甚至在内存中创建一个内存位图。由于BMP格式的图像没有经过压缩,占用了大量的空空间,既作为程序的外部文件,又作为程序的内部资源,尤其是后者会大大增加可执行文件的长度。由此可见,将BMP文件在VC中的应用替换为压缩率较好的压缩JPEG或GIF图像,无疑是具有吸引力的。

二、设计思路

虽然有一些Active X控件可以操作和处理JPEG、GIF等格式的图像,但总的来说使用起来不是很方便。经过实验探索,作者总结出一种利用COM接口的OLE方法实现上述功能的简单方法。现为读者介绍如下:
接下来我们将使用IPicture的COM接口,有必要了解一下这个图像接口:这个接口主要管理图像对象。像标准字体对象一样,系统也提供图像对象的标准实现。它的主要接口是IPicture和IPictureDisp,后者是从IDispatch接口派生出来的,通过自动化来访问图像的属性。该对象还支持外部接口IPropertyNotifySink,以便用户可以在图像属性更改时做出决定。Image还支持IPersistStream接口,所以可以从IStream接口的一个实例对象中保存和加载自己,IStream接口也支持流对象的数据读写。
我们可以使用OleLoadPicture函数从包含图像数据的流中加载图像。这个函数简化了基于流的图像对象的创建过程,可以创建一个新的图像对象并用流中的内容初始化它。函数的原型是:
stdapi ole load picture(istream * p stream,//指向包含图像数据的流的指针,//从流中读取的字节数,BOOL fRunmode,//图像属性的初始值,REFIID riid,//涉及的接口标识符,描述要返回的接口指针的类型,VOID ppvObj // in

第三,具体实施

在显示图像之前,必须先获取图像文件的存储路径。这里使用标准的文件打开对话框选择图像文件,文件名存储在CString类型的变量m_sPath中:
cfiledialog DLG (true," jpg "," *。jpg ",
ofn _ hidereadonly | ofn _ overwrite prompt,
"JPEG文件(*。jpg)|*。jpg|GIF文件(*。gif) | *。gif | ",null);
if(dlg。DoModal()= = IDOK)
{
m _ sPath = DLG。get pathname();
Invalidate();
}
为了简单起见,图形显示的代码直接用可视化类中的OnDraw编写。首先打开文件并判断其可用性,将文件内容放入流接口IStream的对象pStm:
IStream * pStm;
CFileStatus f status;
CFile文件;
长CB;
……
if (file。打开(m_Path,CFile::modeRead)&&file。GetStatus(m_Path,fstatus)&& ((cb = fstatus.m_size)!=-1))
{
h global h global = global alloc(GMEM _可移动,CB);
LP void pvData = NULL;
if (hGlobal!= NULL)
{
if((pvData = global lock(h global))!= NULL)
{
文件。ReadHuge(pvData,CB);
global unlock(h global);
createstreamongglobal(h global,TRUE,& pStm);
}
}
}
然后,直接调用OleLoadPicture函数从流中加载图像:
ipiture * ppic;
……
oleload picture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LP void *)& pPic));
由于该功能有时会导致失败,我们应该使用SUCCEEDED宏做一些适当的保护工作。只有数据加载成功,才能继续下面的图像显示工作:
if(成功(ole load picture (pstm,fstatus.m _ size,true,IID _ IPICTURE,(LPVOID *)& pPic)))
{
OLE _ XSIZE _ HIMETRIC hm width;
OLE _ YSIZE _ HIMETRIC hm height;
pPic-> get _ Width(& hm Width);
pPic-> get _ Height(& hm Height);
double fX,fY;
……
fX =(double)pDC-> GetDeviceCaps(HORZRES)*(double)hm width/((double)pDC-> GetDeviceCaps(HORZSIZE)* 100.0);
fY =(double)pDC-> GetDeviceCaps(VERTRES)*(double)hm height/((double)pDC-> GetDeviceCaps(VERTSIZE)* 100.0);
if(Failed(ppic-> render(* PDC,0,0,(dword) FX,(dword) fy,0,hm height,hm width,-hm height,null)))
afxmessagebox("渲染图像失败!");
pPic-> Release();
}
else
afxmessagebox("未能从流中加载图像!");
其中,显示工作主要由IPicture接口对象的Render函数完成,主要用于将图片的指定部分绘制到指定设备环境的指定位置。原型如下:
HRESULT Render( hdc hdc,//用于渲染图像的设备环境句柄
long x,//HDC
long y上的横坐标,//HDC
long CX上的纵坐标,//图像宽度
//图像高度
ole _ xpos _ himetricsrc,//源图像上的水平偏移量
ole _ ypos _ himetricsrc,//源图像上的垂直偏移量[. //源图像上的水平副本数
ole _ ysize _ himetricsrc,//源图像上的垂直副本数
lprect prcwbounds//指向目标元设备的环境句柄的指针);

总结:到目前为止,JPEG、GIF等标准图像都可以通过上面的代码显示在程序的客户端区域。但对于多幅图片(即动画)的GIF格式图像,目前只能显示第一帧。如果想完整的展示GIF动画的全过程,需要外部Active X控件的支持。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 在VC下显示JPEG、GIF格式图像的一种简便方法

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情