张晓华的博客

        2005年,最后一场雪,还是下了,虽然凄凉了一些!
posts - 185, comments - 100, trackbacks - 8, articles - 1

MFC 加载 和显示图片的几个函数与例子

Posted on Monday, June 23, 2008 11:44 PM

使用IPicture::Render 绘制图片的方法说明:

  HRESULT Render(
                  HDC hdc, //Handle of device context on which to render the image  
                           //绘图设备
                  long x,  //Horizontal position of image in hdc
                           //绘图设备上的X起始坐标
                  long y,  //Vertical position of image in hdc
                           //绘图设备上的Y起始坐标
                  long cx, //Horizontal dimension of destination rectangle
                           //绘图设备上的水平像素单位数(宽)
                  long cy, //Vertical dimension of destination rectangle
                           //绘图设备上的垂直像素单位数(高)
                  OLE_XPOS_HIMETRIC xSrc,
                           //Horizontal offset in source picture
                           //原图的X起始坐标
                  OLE_YPOS_HIMETRIC ySrc,
                           //Vertical offset in source picture
                           //原图的Y起始坐标
                  OLE_XSIZE_HIMETRIC cxSrc,
                           //Amount to copy horizontally in source picture
                           //总计拷贝的水平像素单位数(宽)
                  OLE_YSIZE_HIMETRIC cySrc,
                           //Amount to copy vertically in source picture
                           //总计拷贝的垂直像素单位数(高)
                  LPCRECT prcWBounds
                           //Pointer to position of destination for a metafile hdc
                           //图源文件指针
                );
        范例:
          HRESULT  hr=m_lppi->Render(pDC->m_hDC,0,0,100,100,0,0,11774,20320,&rc);

使用CreateFile取得文件句柄的方法说明
    HANDLE WINAPI CreateFile(
                  LPCTSTR lpFileName,  
                             //The name of the object to be created or opened.
                             //打开或者新建的文件名
                  DWORD dwDesiredAccess,  
                             // The access to the object, which can be read, write, or both.
                             //  文件访问权限  常用的是 GENERIC_EXECUTE  / GENERIC_READ  /GENERIC_WRITE
                  DWORD dwShareMode,  
                             //  The sharing mode of an object, which can be read, write, both, or none
                             //   文件的共享模式,常用的是  FILE_SHARE_DELETE  / FILE_SHARE_READ  /FILE_SHARE_WRITE ,0表示不共享
                  LPSECURITY_ATTRIBUTES lpSecurityAttributes,  
                             //  A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not the returned handle can be inherited by child processes.
                             //  详细内容,参见 msdn 的相关描述,我就不翻译了
                  DWORD dwCreationDisposition,  
                             //  An action to take on files that exist and do not exist.
                             //  详细内容,参见 msdn 的相关描述,我就不翻译了
                  DWORD dwFlagsAndAttributes,  
                             //  The file attributes and flags.
                             // 详细内容,参见 msdn 的相关描述,我就不翻译了
                  HANDLE hTemplateFile  
                             //  A handle to a template file with the GENERIC_READ access right. The template file supplies file attributes and extended attributes for the file that is being created. This parameter can be NULL.
                             //  详细内容,参见 msdn 的相关描述,我就不翻译了
                );
                
    范例:
          HANDLE hFile=CreateFile(_T("\\aaa.jpg"),GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
            

    
使用IPersistStream::Load获取LPPICTURE对象的方法:
    STDAPI OleLoadPicture(
                  IStream * pStream,
                               //Pointer to the stream that contains picture's data
                  LONG lSize,  //Number of bytes read from the stream
                  BOOL fRunmode,
                               //The opposite of the initial value of the picture's
                               // property
                  REFIID riid, //Reference to the identifier of the interface
                               // describing the type of interface pointer to return
                  VOID ppvObj  //Address of output variable that receives interface
                               // pointer requested in riid
                );

其他方法:

//按文件大小分配内存
                 LPVOID pvData;
                 HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);
//锁定内存
                pvData=GlobalLock(hGlobal);            
//读取文件到内存    
                DWORD dwFileRead=0;
                BOOL bRead=ReadFile(hFile,pvData,dwFileSize,&dwFileRead,NULL);
//从已分配内存生成IStream流
                HRESULT hr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);
                hr=OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,(LPVOID*)&(*lppi));
                pstm->Release();


一个相对完整的步骤

//加载图片
BOOL CPicTestDlg::LoadMyJpegFile(CString fname,LPPICTURE *lppi)
    {
        HANDLE hFile=CreateFile(fname,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
            if(hFile==INVALID_HANDLE_VALUE)
            {
                CString str;
                str.Format(_T("%s无法被打开"),fname);
                MessageBox(str);
                return FALSE;
            }
            
        //取得文件大小
        DWORD dwFileSize=GetFileSize(hFile,NULL);
            if((DWORD)-1==dwFileSize)
            {
                CloseHandle(hFile);
                MessageBox(_T("图像文件是空的"));
                return FALSE;
            }

        //读取图像文件
        
        LPVOID pvData;
        
        //按文件大小分配内存
        HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);
            if(NULL==hGlobal)
            {
                CloseHandle(hFile);
                MessageBox(_T("内存不足,无法分配足够内存"));
                return FALSE;
            }

        pvData=GlobalLock(hGlobal);
            if(NULL==pvData)
            {
                GlobalUnlock(hGlobal);
                CloseHandle(hFile);
                MessageBox(_T("无法锁定内存"));
                return FALSE;
            }

        DWORD dwFileRead=0;
        
        BOOL bRead=ReadFile(hFile,pvData,dwFileSize,&dwFileRead,NULL);
        
        GlobalUnlock(hGlobal);
        
        CloseHandle(hFile);
        
            if(FALSE==bRead)
            {
                MessageBox(_T("读文件出错"));
                return FALSE;
            }
        LPSTREAM pstm=NULL;
        
        //从已分配内存生成IStream流
        
        HRESULT hr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);
            if(!SUCCEEDED(hr))
            {
                MessageBox(_T("生成流操作失败"));
                if(pstm!=NULL)
                    pstm->Release();
                return FALSE;
            }else if(pstm==NULL){
                MessageBox(_T("生成流操作失败"));
                return FALSE;
            }
            
            if(!*lppi)
                (*lppi)->Release();
                
        hr=OleLoadPicture(pstm,dwFileSize,FALSE,IID_IPicture,(LPVOID*)&(*lppi));
        
        pstm->Release();
            if(!SUCCEEDED(hr))
            {
                MessageBox(_T("加载操作失败"));
                return FALSE;
            }else if(*lppi==NULL){
                MessageBox(_T("加载操作失败"));
                return FALSE;
            }
        return TRUE;
    }

//绘制图片



        TCHAR strPath[MAX_PATH];
        memset(strPath,0,MAX_PATH);
        //得到当前路径
        GetCurrentDirectory(MAX_PATH,strPath);
        //定义图片路径
        wcscat_s(strPath,MAX_PATH,_T("\\145.bmp"));
        //加载图片到 m_lppi
        m_bHadLoad=LoadMyJpegFile(strPath,&m_lppi);
        //取得绘图设备
        CDC *pDC=GetDC();
        //定义绘图矩形区域
        CRect rc;
        //得到图片长宽
        long hmWidth=0;
        long hmHeight=0;
        m_lppi->get_Height(&hmHeight);
        m_lppi->get_Width(&hmWidth);
        //定义区域与设备关联
        GetClientRect(&rc);
        int nWidth,nHeight;
        //得到设备的长宽
        nWidth=rc.Width();
        nHeight=rc.Height();
        //绘制图片到设备区域
        HRESULT  hr=m_lppi->Render(pDC->m_hDC,nWidth,0,-nWidth,nHeight,hmWidth,hmHeight,-hmWidth,-hmHeight,&rc);
        
使用以上内容可以在mfc的窗体中的任何地方绘制图片,重绘的时候,需要在方法OnPaint()中加以定义,另外可以在OnInitDialog()中提前加载图片到内存中.










 
 

 

Post Comment

Title  
Name  
Url
Comment   
Protected by Clearscreen.SharpHIPEnter the code you see: