• 利用IPicture接口实现显示BMP/JPG/GIF图像


    12.1.3  利用IPicture接口实现显示BMP/JPG/GIF图像

    1.问题阐述

    在VB 中显示一个图像非常简单,只要将图像控件拖入到面板中,设置相应的属性即可。其实它的显示原理只是调用Windows的Ipicture接口,本节重点介绍了这一接口。

    2.实现技巧

    如何利用IPicture显示图像呢?首先了解一下这个接口的内容和作用、IPicture接口是一个COM类,操纵着图像对象及其属性。图像对象提供对位图的抽象,而Windows负责BMP、JPG和GIF位图的标准实现。IPictrue接口支持BMP、DIB、EMF、GIF、ICO、JPG、WMF格式图片的显示,但只能保存BMP和ICO格式的图片。下面是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接口和其他的接口不同,这个接口的实例不用CoCreateInstance来创建,而是采用一个专门的函数OleLoadPicture创建IPicture接口的实例。OleLoadPicture的声明和参数的含义如下所示:

     

     

    STDAPI OleLoadPicture(
    IStream * pStream,
    LONG lSize, 
    BOOL fRunmode,
    REFIID riid,
    VOID ppvObj 
    );

     

    第一个参数pStream指向包含有图像数据的流的指针,第二个参数lSize为从流中读取的字节数,第三个参数fRunmode为图像属性对应的初值,第四个参数riid为涉及到的接口标识描述要返回的接口指针的类型,第五个参数ppvObj为在rrid中用到的接口指针变量的地址。

    3.实例代码

    本实例使用IPicture接口完成图像JPG和GIF等图像的显示。建立一个基于单文档的工程,工程名为PictureRend。

    在PiectureRend.h的函数InitInstance( )中初始化COM库,在程序退出的时候,关闭COM库,加载COM库的代码如下:

    BOOL CPictureRendApp::InitInstance()
    {
    //--------------------------------------------------------------------------
    AfxEnableControlContainer();
    *****************************
    }

     

    关闭COM库的代码如下:

     

     

     int CPictureRendApp::ExitInstance() 
    {
    CoUninitialize(); 
    return CWinApp::ExitInstance();
    }

     

    在PictureRendView.h中声明:

      

    CFile m_File;
    IStream* m_pStream ;
    IPicture* m_pPicture ;
    LONG m_nWidth;
    LONG m_nHeight;

     

    在打开菜单中,获取打开的图像的路径名,代码如下:

     

    void CPictureRendApp::OnFileOpen()
    {
    CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY
    |OFN_OVERWRITEPROMPT,
    "文件 (*.jpg)|*.jpg|文件 (*.gif)|*.gif|All Files (*.*)|*.*||", NULL);
    if( IDOK != dlg.DoModal())
    {
    return;
     }
    m_strPicPath = dlg.GetPathName();
    PostMessage(((CMainFrame*)m_pMainWnd)->GetActiveView()->m_hWnd,
    WM_ON_RENDER_PIC,0,0);//一旦打开文件,消息响应
    }

     

    注意,在响应“打开”消息的时候,要对消息映射的地方加以改变,如下:

     

     ON_COMMAND(ID_FILE_OPEN,OnFileOpen)。

     

    在View中添加渲染图像,代码如下:

    void CPictureRendView::OnRenderPic()
    {
    HRESULT hr;
    CClientDC dc(this);
    m_File.Open( theApp.m_strPicPath, CFile::modeRead | CFile::shareDenyNone );
    // 读入文件内容
    DWORD dwSize = m_File.GetLength();
    HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, dwSize );
    LPVOID lpBuf = ::GlobalLock( hMem );
    m_File.ReadHuge( lpBuf, dwSize );
    m_File.Close();
     m_pStream = NULL;
    m_pPicture = NULL;
     // 由 HGLOBAL 得到 IStream,参数 TRUE 表示释放 IStream 的同时,释放内存
    hr = ::CreateStreamOnHGlobal( hMem, TRUE, &m_pStream );
    ::GlobalUnlock( hMem );
     ASSERT ( SUCCEEDED(hr) );
    hr = ::OleLoadPicture(
    m_pStream, dwSize, TRUE, IID_IPicture, ( LPVOID * )&m_pPicture );
    ASSERT(hr==S_OK);
    long nWidth,nHeight;     // 宽高,MM_HIMETRIC 模式,单位是0.01毫米
    m_pPicture->get_Width( &m_nWidth );    // 宽
    m_pPicture->get_Height( &m_nHeight );   // 高
    ////////原大小显示//////
    CSize sz( m_nWidth, m_nHeight );
    dc.HIMETRICtoDP( &sz );
    // 转换 MM_HIMETRIC 模式单位为 MM_TEXT 像素单位
    m_pPicture->Render(dc.m_hDC,0,0,sz.cx,sz.cy,
    0,m_nHeight,m_nWidth,-m_nHeight,NULL);
    }

     

    在程序退出时,释放数据流和接口指针:

     

     if ( m_pPicture ) m_pPicture->Release();  // 释放 IPicture 指针
    if ( m_pStream ) m_pStream->Release();    // 释放 IStream 指针,同时释放了 hMem

     

    运行!

     

     
    图12-6  IPicture接口的使用
  • 相关阅读:
    【CSP2019模拟】题解
    【Codeforces 868 G】— El Toll Caves(类欧几里得)
    【Codeforces 868 G】— El Toll Caves(类欧几里得)
    如何写出规范的代码? 做一名追求极致的软件工程师!
    浏览器原理
    URL(待整合到HTTP书中哦)
    FTP服务器
    background-image 和 img
    XML的总结学习
    逻辑思维 代码逻辑
  • 原文地址:https://www.cnblogs.com/tianlangshu/p/1989536.html
Copyright © 2020-2023  润新知