




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在MFC应用程序中显示JPG/GIF图像文件如果你是一个使用Visual Basic编程的程序员,要在程序中显示JPG或者GIF图像简直易如反掌,将图像控件拖到Form中就可以了。但是C+程序员要显示同样格式的图像文件却没有那么轻松,那么是不是要自己编写JPG解压缩代码呢?当然不用那么复杂啦!本实例将针对这个问题讨论如何在MFC中显示JPG或者GIF格式的图像文件。一、实现方法用Visual Basic写图像显示程序之所以如此轻松,完全是利用了琳琅满目的图像处理控件,它们处理了显示图像文件的所有底层工作,而C+程序员为了实现相同的功能必须忙乎半天。其实,C/C+程序员也能使用那些Visual Basic程序员所用的(或者说几乎一样的)图像控件。Visual Basic用的图像控件实际上都是基于一个系统级的COM类-IPicture。下面是有关Ipicture类的方法描述:get_Handle():返回图像对象的Windows GDI句柄;get_Hpal():返回图像对象当前使用的调色板拷贝;get_Type():返回当前图像对象的的图像类型; get_Width():返回当前图像对象的图像宽度; get_Height():返回当前图像对象的图像高度; Render():在指定的位置、指定的设备上下文上绘制指定的图像部分; set_Hpal():设置当前图像的调色板; get_CurDC():返回当前选中这个图像的设备上下文; SelectPicture():将一个位图图像选入给定的设备上下文,返回选中图像的设备上下文和图像的GDI句柄 ;get_KeepOriginalForma():返回图像对象KeepOriginalFormat 属性的当前值; put_KeepOriginalFormat():设置图像对象的KeepOriginalFormat 属性; PictureChanged():通知图像对象它的图像资源改变了; SaveAsFile():将图像数据存储到流中,格式与存成文件格式相同; get_Attributes():返回图像位属性当前的设置;从上面的方法可以看出,Ipicture类操纵着图像对象及其属性。图像对象提供对位图的抽象,而Windows负责BMP、JPG和GIF等格式的标准实现。程序员要做的只是实例化Ipicture类对象,然后调用其Render()函数。与通常使用接口的方式不同,这里实例的创建我们不用CoCreateInstance()函数,而是用一个专门的函数OleLoadPicture(),具体实现代码如下: IStream* pstm = / 需要一个流(stream)IPicture* pIPicture;hr = OleLoadPicture(pstm, 0, FALSE, IID_IPicture, (void*)&pIPicture); OleLoadPicture()函数从数据流中加载图像并创建一个可用来显示图像的新IPicture对象。 rc = / 显示图像的矩形IPicture 负责处理所有琐事,以便确定图形之格式,如 Windows 位图、JPEG或者GIF文件-甚至是图标和元文件(metafiles)。当然啦,所有这些的实现细节是需要技巧的,为此本实例写了一个Demo程序Myimgapp来示范这些IPicture的使用方法。Myimgapp是个典型的MFC文档/视图程序,在编写这个程序之前,首先对 IPicture COM接口进行封装,之所以要这么做,主要是考虑到并不是每一个程序员都能熟练运用COM接口进行编程,另外将IPicture的主要功能封装在C+类中可以使我们的问题更容易解决,封装的这个C+类名字叫做CPicture。它的定义和实现细节请参考本文提供的源代码。 本实例在这个类中将复杂而陌生的COM风格的参数映射成MFC程序员更为熟悉的类型。例如,CPicture可以让你直接从文件名加载一幅图像,CFile或者CArchive,而不用去处理流,CPicture:Render()替你完成了IPicture中所有令人讨厌的但又是必须的HIMETRIC平滑转换工作。CPicture甚至具备了一个Load()函数,它可以从资源数据中加载图像,所以你只要用下面的代码就可以显示资源中的图像:CPicture pic(ID_MYPIC); / 加载图像CRect rc(0,0,0,0); / 使用缺省的rcpic.Render(pDC, rc); / 显示图像 CPicture:Render提供一个显示图片的矩形。IPicture 对图像进行延伸处理。如果传递一个空矩形,则CPicture用图像本身的大小-不进行延伸处理。对于图像本身而言,CPicture查找IMAGE类型的资源,所以在资源文件中必须要在程序的资源文件中加入如下语句来添加图像资源:IDR_MYPIC IMAGE MOVEABLE PURE resMyPic.jpg。 CPicture是个很棒的傻瓜类,它具备一个 ATL 智能指针CComQIPtr指向IPicture接口,通过调用OleLoadPicture来初始化不同的Load函数。CPicture提供了常用的打包函数来调用底层的IPicture。CPicture只封装了那些在Demo例子程序中要用到的方法。如果读者朋友需要调用IPicture:get_Handle或其它一些很少用到的IPicture方法,可以自己尝试编写相应的打包代码。 总之,IPicture/CPicture简化了图像的显示,它甚至可以实现调色板的识别这样复杂的处理,读者朋友完全可以抛开老式DIB 图像绘制方法,如加载调色板、BitBlts()、StretchBlts()等操作-这一切IPicture全都可以搞掂。程序中有一个消息处理器值得一提:它就是视图类的OnEraseBkgnd()函数,当要显示的图像比客户区小的时候,这个函数必须绘制空白区域,OnEraseBkgnd()函数创建一个与图像大小相等的切边(clip)矩形,然后将客户区填成黑色,之所以要创建切边矩形,主要是避免当改变窗口大小时出现的抖动-FillRect()不绘制切边矩形内的区域,此乃Windows图形处理的常识。 二、编程步骤1、 启动Visual C+6.0,生成一个单文档视图结构的应用程序,视图类的基类为CscrollView,同时将该程序命名为Myimgapp;2、 在应用程序的项目代码中添加CPicture类;工具栏上添加图像显示比例的按钮,具体参加代码部分;3、 使用资源编辑器向程序中添加Jepg格式的图像资源;4、 添加代码,编译运行程序。三、程序代码/ Picture object-encapsulates IPicture#pragma once#include class CPicture public:CPicture();CPicture();/ Load frm various sosurcesBOOL Load(UINT nIDRes);BOOL Load(LPCTSTR pszPathName);BOOL Load(CFile& file);BOOL Load(CArchive& ar);BOOL Load(IStream* pstm);/ render to device contextBOOL Render(CDC* pDC, CRect rc=CRect(0,0,0,0),LPCRECT prcMFBounds=NULL) const;CSize GetImageSize(CDC* pDC=NULL) const;operator IPicture*() return m_spIPicture; void GetHIMETRICSize(OLE_XSIZE_HIMETRIC& cx, OLE_YSIZE_HIMETRIC& cy) const cx = cy = 0;const_cast(this)-m_hr = m_spIPicture-get_Width(&cx);ASSERT(SUCCEEDED(m_hr);const_cast(this)-m_hr = m_spIPicture-get_Height(&cy);ASSERT(SUCCEEDED(m_hr);void Free() if (m_spIPicture) m_spIPicture.Release();protected:CComQIPtrm_spIPicture; / ATL smart pointer to IPictureHRESULT m_hr; / last error code;/ CPicture implementation#include StdAfx.h#include Picture.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifCPicture:CPicture()CPicture:CPicture()BOOL CPicture:Load(UINT nIDRes) / Load from resource. Looks for IMAGE type./ find resource in resource fileHINSTANCE hInst = AfxGetResourceHandle();HRSRC hRsrc = :FindResource(hInst,MAKEINTRESOURCE(nIDRes),IMAGE); / typeif (!hRsrc)return FALSE;/ load resource into memoryDWORD len = SizeofResource(hInst, hRsrc);BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);if (!lpRsrc)return FALSE;/ create memory file and load itCMemFile file(lpRsrc, len);BOOL bRet = Load(file);FreeResource(hRsrc);GlobalFree(lpRsrc);return bRet;BOOL CPicture:Load(LPCTSTR pszPathName) / Load from path name.CFile file;if (!file.Open(pszPathName, CFile:modeRead|CFile:shareDenyWrite)return FALSE;BOOL bRet = Load(file);file.Close();return bRet;BOOL CPicture:Load(CFile& file) / Load from CFileCArchive ar(&file, CArchive:load | CArchive:bNoFlushOnDelete);return Load(ar);/ Load from archive-create stream and load from stream.BOOL CPicture:Load(CArchive& ar)CArchiveStream arcstream(&ar);return Load(IStream*)&arcstream);/ Load from stream (IStream). This is the one that really does it: call/ OleLoadPicture to do the work.BOOL CPicture:Load(IStream* pstm)Free();HRESULT hr = OleLoadPicture(pstm, 0, FALSE,IID_IPicture, (void*)&m_spIPicture);ASSERT(SUCCEEDED(hr) & m_spIPicture); return TRUE;/ Render to device context. Covert to HIMETRIC for IPicture.BOOL CPicture:Render(CDC* pDC, CRect rc, LPCRECT prcMFBounds) constASSERT(pDC);if (rc.IsRectNull() CSize sz = GetImageSize(pDC);rc.right = sz.cx;rc.bottom = sz.cy;long hmWidth,hmHeight; / HIMETRIC unitsGetHIMETRICSize(hmWidth, hmHeight);m_spIPicture-Render(*pDC, rc.left, rc.top, rc.Width(), rc.Height(),0, hmHeight, hmWidth, -hmHeight, prcMFBounds);return TRUE;/ Get image size in pixels. Converts from HIMETRIC to device coords.CSize CPicture:GetImageSize(CDC* pDC) constif (!m_spIPicture)return CSize(0,0);LONG hmWidth, hmHeight; / HIMETRIC unitsm_spIPicture-get_Width(&hmWidth);m_spIPicture-get_Height(&hmHeight);CSize sz(hmWidth,hmHeight);if (pDC=NULL) CWindowDC dc(NULL);dc.HIMETRICtoDP(&sz); / convert to pixels else pDC-HIMETRICtoDP(&sz);return sz;/ Picture view is a typical scroll view.#include Doc.hclass CPictureView : public CScrollView public:virtual CPictureView();CPictureDoc* GetDocument() return (CPictureDoc*)m_pDocument; protected:BOOL m_rcImage; / rect to display image inUINT m_iHowScale; / how to scale imageCPictureView();void GetImageRect(CRect& rc);void SetScrollSizes();virtual void OnDraw(CDC* pDC); / overridden to draw this viewvirtual void OnInitialUpdate(); / called first time after construct/ command/message handlersafx_msg void OnViewScale(UINT nID);afx_msg void OnUpdateViewScale(CCmdUI* pCmdUI);afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnSize(UINT nType, int cx, int cy);DECLARE_DYNCREATE(CPictureView)DECLARE_MESSAGE_MAP();/ CPictureView#include StdAfx.h#include View.h#include resource.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifIMPLEMENT_DYNCREATE(CPictureView, CScrollView)BEGIN_MESSAGE_MAP(CPictureView, CScrollView)ON_WM_ERASEBKGND()ON_WM_SIZE()ON_COMMAND_RANGE(ID_VIEW_TOFIT, ID_VIEW100, OnViewScale)ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_TOFIT, ID_VIEW100, OnUpdateViewScale)END_MESSAGE_MAP()CPictureView:CPictureView()m_iHowScale = ID_VIEW_TOFIT;CPictureView:CPictureView()void CPictureView:OnInitialUpdate()SetScrollSizes();/ Set scroll sizes based on picture. Page size = client hieight/width;/ line size = 1/10 of this.void CPictureView:SetScrollSizes()CRect rcClient;GetClientRect(&rcClient);CRect rcImage;GetImageRect(rcImage);CSize szTotal = rcImage.Size();CSize szPage = rcClient.Size();CSize szLine = szPage;szLine.cx /= 10;szLine.cy /= 10;CScrollView:SetScrollSizes(MM_TEXT, szTotal, szPage, szLine);Invalidate();/ View was sized: readjust scroll sizes if Im in zoom to fit modevoid CPictureView:OnSize(UINT nType, int cx, int cy)CScrollView:OnSize(nType, cx, cy);if (m_iHowScale=ID_VIEW_TOFIT) SetScrollSizes();/ Erase the background. This is required in case the image is smaller than/ the client area, to paint the extra background. Use clipping to avoid flicker.BOOL CPictureView:OnEraseBkgnd(CDC* pDC)CPictureDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ get client rectangleCRect rcClient;GetClientRect(&rcClient);CRect rc = rcClient;/ get image rectangleCRect rcImage;GetImageRect(rcImage);rc = rcImage;CPoint pt = pDC-GetViewportOrg();CSize sz = GetTotalSize();/ create clipping regionCRgn clipRgn;clipRgn.CreateRectRgnIndirect(&rcClient);pDC-SelectClipRgn(&clipRgn);pDC-ExcludeClipRect(&rcImage);CBrush brush(RGB(0,0,0); / blackpDC-FillRect(&rcClient, &brush);pDC-SelectClipRgn(NULL);return TRUE;/ Draw the picture - call CPicture to do it.void CPictureView:OnDraw(CDC* pDC)CPictureDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CPicture* ppic = pDoc-GetPicture();ASSERT(ppic);if (*ppic) CRect rc;GetImageRect(rc);ppic-Render(pDC,rc);/ Get image rectangle, scaled for curre
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2017正规租房合同范本
- 植物学奥赛题目及答案
- 人员培训与开发试题及答案(一)
- 人教版高一上学期语文期末考试试卷(含答案)
- 直营店招聘合同范本
- 法律咨询服务合同
- 俄语试卷题目及答案
- 健康保障考试试题题库及答案
- 2025年实验幼儿园教职工考核量化细则
- CN222960731U 环形跟踪上料站 (温州优匠工品科技有限公司)
- 2025至2030中国半导体晶圆清洗设备(SWCE)市场现状调查及未来前景展望报告
- 2025混凝土结构施工清包工合同
- 社区公共卫生护理与干预措施试题及答案
- 起重吊装专项应急预案
- 消杀知识考试题及答案
- 医学资料 Picc导管皮肤相关性皮炎案例与分析学习课件
- 重症血液净化血管通路的建立与应用中国专家共识解读2025
- 2025年乡村医生考试题库:常见疾病诊疗与公共卫生服务体系建设试题集
- 能源管理体系及节能知识培训课件
- 2025年度股权代持协议书:国有企业股权代持与监管协议
- 土壤改良施工方案
评论
0/150
提交评论