1、利用IPicture接口加载、显示图片

IPicture接口管理一个图片对象和它的属性。图片对象提供对Bitmap Icon Metafile的语言不相关的抽象支持。图像对象的主要接口是IPicture和IPictureDisp。IPictureDisp从IDispatch继承,提供了通过自动化访问图片属性的能力。图片对象可通过OleCreatePictureIndirect创建。关于IPicture支持的其他接口和方法可以看MSDN,一般创建图片对象可以用OleLoadPicture函数,它简化了基于流内容创建图片对象。

IPicture接口管理一个图片对象和它的属性。图片对象提供对Bitmap Icon Metafile的语言不相关的抽象支持。图像对象的主要接口是IPicture和IPictureDisp。IPictureDisp从IDispatch继承,提供了通过自动化访问图片属性的能力。图片对象可通过OleCreatePictureIndirect创建。关于IPicture支持的其他接口和方法可以看MSDN,一般创建图片对象可以用OleLoadPicture函数,它简化了基于流内容创建图片对象。下面的代码中有两个未定义的变量是FilePath和hDC。 
//FilePath是从外部传入的图片路径 
//打开文件 
HANDLE hFile = CreateFile(FilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 
_ASSERTE(INVALID_HANDLE_VALUE != hFile); 
//取文件大小 
DWORD dwFileSize = GetFileSize(hFile, NULL); 
_ASSERTE(-1 != dwFileSize); 
LPVOID pvData = NULL; 
//分配内存,准备读入图片文件的数据 
//GlobalAlloc从堆分配指定字节的内存区域 
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); 
_ASSERTE(NULL != hGlobal); 
//GlobalLock函数锁住一个全局的内存对象同时返回一个指向对象首字节的指针 
pvData = GlobalLock(hGlobal); 
_ASSERTE(NULL != pvData); 
DWORD dwBytesRead = 0; 
//读取文件的数据到分配的全局内存 
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL); 
_ASSERTE(FALSE != bRead); 
GlobalUnlock(hGlobal); 
CloseHandle(hFile);

//到此,我们已经把文件的数据读到了内存当中

LPSTREAM pstm = NULL; 
//从全局内存创建IStream接口指针 
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm); 
_ASSERTE(SUCCEEDED(hr) && pstm); 
//根据图片文件创建IPicture接口指针 
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture); 
_ASSERTE(SUCCEEDED(hr) && gpPicture); 
pstm->Release();

//至此,IPicture接口建立好,下面开始画图片 
//hDC是外部传入的画图设备 
long hmWidth; 
long hmHeight; 
gpPicture->get_Width(&hmWidth); 
gpPicture->get_Height(&hmHeight); 
//转换himetric距离为pixels距离,1英寸=25.4毫米 
int nWidth = MulDiv(hmWidth, GetDeviceCaps(hDC, LOGPIXELSX), 2540); 
int nHeight = MulDiv(hmHeight, GetDeviceCaps(hDC, LOGPIXELSY), 2540); 
RECT rc; 
GetClientRect(hWnd, &rc); 
//IPicture::Render显示图片 
gpPicture->Render(hDC, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);

2、C++如何调用图片 
有很多办法 ,比如用IPicture,用CBitmap //MFC,更直接的是,用File进行文件操作,用BitBlt显示,具体代码你用以上关键字Google下 
这里给你推荐几个,末尾给你附一个网上可以找到的CPicture类(需MFC支持): 
——-IPicture 
// pDoc为文档对象指针 
// pDC为设备描述表指针 
::CoInitialize(NULL); // COM 初始化 
HRESULT hr; 
CFile file; 
file.Open(pDoc->GetPathName(), CFile::modeRead | CFile::shareDenyNone ); // 读入文件内容 
DWORD dwSize = file.GetLength(); 
HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, dwSize ); 
LPVOID lpBuf = ::GlobalLock( hMem ); 
file.ReadHuge( lpBuf, dwSize ); 
file.Close(); 
::GlobalUnlock( hMem ); 
IStream * pStream = NULL; 
IPicture * pPicture = NULL; 
// 由 HGLOBAL 得到 IStream,参数 TRUE 表示释放 IStream 的同时,释放内存 
hr = ::CreateStreamOnHGlobal( hMem, TRUE, &pStream ); 
ASSERT ( SUCCEEDED(hr) ); 
hr = ::OleLoadPicture( pStream, dwSize, TRUE, IID_IPicture, ( LPVOID * )&pPicture ); 
ASSERT(hr==S_OK); 
long nWidth,nHeight; // 宽高,MM_HIMETRIC 模式,单位是0.01毫米 
pPicture->get_Width( &nWidth ); // 宽 
pPicture->get_Height( &nHeight ); // 高 
CRect rect; 
GetClientRect(&rect); 
CSize sz( nWidth, nHeight ); 
pDC->HIMETRICtoDP( &sz ); // 转换 MM_HIMETRIC 模式单位为 MM_TEXT 像素单位 
long x, y, cx, cy; 
// 原始大小 
/* 
cx = sz.cx; 
cy = sz.cy; 
x = rect.Width() / 2 – cx / 2; 
y = rect.Height() / 2 – cy / 2; 
*/ 
// 自动适应窗口 
double fRatePic, fRateWnd; 
fRatePic = (double)sz.cx / (double)sz.cy; 
fRateWnd = (double)rect.Width() / (double)rect.Height(); 
if (fRatePic > fRateWnd) 

cx = rect.Width(); 
cy = (long)(rect.Width() / fRatePic); 

else 

cx = (long)(rect.Height() * fRatePic); 
cy = rect.Height(); 

if (cx == rect.Width()) 

x = 0; 
y = rect.Height() / 2 – cy / 2; 

if (cy == rect.Height()) 

x = rect.Width() / 2 – cx / 2; 
y = 0; 

pPicture->Render(pDC->m_hDC, x, y, cx, cy, 
0, nHeight, nWidth, -nHeight, NULL); 
if ( pPicture ) pPicture->Release();// 释放 IPicture 指针 
if ( pStream ) pStream->Release(); // 释放 IStream 指针,同时释放了 hMem 
::CoUninitialize(); 
——————————–CBitmap: 
HBITMAP bitmap; 
bitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),strFileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
m_backBitmap.DeleteObject(); 
if(!m_backBitmap.Attach(bitmap)) 

MessageBox("导入背景图失败!","提示",MB_OK); 
return; 

———————-File:略 
前提是你要知道图片的编码格式 
一般比较简单的是BMP,包括 
BITMAPFILEHEADER,BITMAPINFO,BITMAPINFOHEADER 
如果图片采用了压缩算法可能会麻烦一点, 
关于详细情况你也以Google一下 
附CPicture(引用自网上) 
// Picture.h: interface for the CPicture 
#ifndef PICTURE_H 
#ifndef picture_h 
#define PICTURE_H 
#define picture_h 
#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
class CPicture 

public: 
CPicture(); 
virtual ~CPicture(); 
public: 
BOOL LoadPicture(UINT nResource, LPCTSTR lpszResType) 
{return LoadPicture(MAKEINTRESOURCE(nResource), lpszResType);} 
BOOL LoadPictureFromFile(LPCTSTR lpszFileName); 
BOOL LoadPicture(LPCTSTR lpszResource,LPCTSTR lpszResType); 
BOOL IsValid(){ return m_pPic!=NULL;} 
CSize GetSize(){return m_size;} 
void Draw(CDC* pDC, LPCRECT lprcDest, LPCRECT lprcSrc); 
void Draw(CDC* pDC, int xDest,int yDest, int cxDest, int cyDest , 
int xSrc ,int ySrc ,int cxSrc ,int cySrc); 
void Release(); 
protected: 
IPicture* m_pPic; 
OLE_XSIZE_HIMETRIC _w_him; 
OLE_YSIZE_HIMETRIC _h_him; 
CSize m_size; 
protected: 
void CalcSize(); 
}; 
#endif // define picture_h 
#endif // define PICTURE_H 
////////////////////////////////////////////////////////////////////// 
// Picture.cpp: implementation of the CPicture class. 
// Lounge Stdio 2003 
// 作者:边城浪子(QQ:16168666) 
// E-mail: krh2001.lpfdiyvbb@163.com 
////////////////////////////////////////////////////////////////////// 
#include "stdafx.h" 
#include "Picture.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CPicture::CPicture() 
:m_pPic(NULL), _h_him(0), _w_him(0), m_size(0,0) 


CPicture::~CPicture() 

Release(); 

void CPicture::Release() 

if(m_pPic != NULL) 

m_pPic->Release(); 
m_pPic = NULL; 
_h_him = _w_him = 0; 
m_size.cx = m_size.cy = 0; 


BOOL CPicture::LoadPicture(LPCTSTR lpszResource, LPCTSTR lpszResType) 

Release(); 
HINSTANCE hInst = AfxFindResourceHandle(lpszResource, lpszResType); 
HRSRC hRsrc = ::FindResource(hInst, lpszResource, lpszResType); 
if(hRsrc == NULL) return FALSE; 
HGLOBAL hGlobal = LoadResource(hInst, hRsrc); 
if(hGlobal == NULL) return FALSE; 
DWORD dwSize = SizeofResource(hInst, hRsrc); 
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize); 
if(hMem == NULL) return FALSE; 
LPVOID pSrc = ::LockResource(hGlobal); 
if(pSrc == NULL) { 
::GlobalFree(hMem); 
return FALSE; 

LPVOID pDes = ::GlobalLock(hMem); 
if(pDes == NULL){ 
//::GlobalUnlock(hGlobal); 
::GlobalFree(hMem); 
return FALSE; 

memcpy(pDes, pSrc, dwSize); 
//GlobalUnlock(hGlobal); 
GlobalUnlock(hMem); 
::FreeResource(hGlobal); 
IStream* pStm = NULL; 
CreateStreamOnHGlobal(hMem, TRUE, &pStm); 
if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic))) 

pStm -> Release(); 
::GlobalFree(hMem); 
pStm = NULL; 
return FALSE; 

pStm->Release(); 
::GlobalFree(hMem); 
CalcSize(); 
return TRUE; 

BOOL CPicture::LoadPictureFromFile(LPCTSTR lpszFileName) 

Release(); 
CFile file; 
if(!file.Open(lpszFileName, CFile::modeRead)) 
return FALSE; 
DWORD dwSize = file.GetLength(); 
HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize); 
if(hMem == NULL) return FALSE; 
LPVOID pDes = ::GlobalLock(hMem); 
if(pDes == NULL){ 
::GlobalFree(hMem); 
return FALSE; 

file.ReadHuge(pDes, dwSize); 
file.Close(); 
GlobalUnlock(hMem); 
IStream* pStm = NULL; 
CreateStreamOnHGlobal(hMem, TRUE, &pStm); 
if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic))) 

pStm -> Release(); 
::GlobalFree(hMem); 
pStm = NULL; 
return FALSE; 

pStm->Release(); 
::GlobalFree(hMem); 
CalcSize(); 
return TRUE; 

void CPicture::CalcSize() 

if(m_pPic == NULL) return; 
m_pPic->get_Width(&_w_him); 
m_pPic->get_Height(&_h_him); 
CDC* pDC = CWnd::GetDesktopWindow()->GetDC(); 
m_size.cx = _w_him; 
m_size.cy = _h_him; 
pDC->HIMETRICtoDP(&m_size); 
CWnd::GetDesktopWindow()->ReleaseDC(pDC); 

void CPicture::Draw(CDC* pDC, LPCRECT lprcDest, LPCRECT lprcSrc) 

if(m_pPic) 

CSize szOrig(lprcSrc->left, lprcSrc->top); 
CSize szSrc(lprcSrc->right – lprcSrc->left, lprcSrc->bottom – lprcSrc->top); 
pDC->DPtoHIMETRIC(&szOrig); 
pDC->DPtoHIMETRIC(&szSrc); 
m_pPic->Render(*pDC, lprcDest->left,lprcDest->top,lprcDest->right-lprcDest->left, 
lprcDest->bottom-lprcDest->top, szOrig.cx, _h_him-szOrig.cy, szSrc.cx, 
-szSrc.cy, NULL); 


void CPicture::Draw(CDC* pDC, int xDest,int yDest, int cxDest, int cyDest , 
int xSrc ,int ySrc ,int cxSrc ,int cySrc) 

Draw(pDC, CRect(xDest, yDest, xDest+cxDest, yDest+cyDest), CRect(xSrc, ySrc, xSrc+cxSrc, ySrc+cySrc)); 
}

IPicture总结的更多相关文章

  1. .NET中操作IPicture、IPictureDisp的小随笔

    [题外话] 最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口.调用仪器的时候需要传输图片,提供的接口里使用了IPicture这个接口,由于以前没接触过,所以查找了一些资料, ...

  2. IPicture、BITMAP、HBITMAP和CBitmap的关系

    1.有关IPicture加载图片后直接Render到内存DC的问题(HBITMAP转换IPicture)Picture的方法get_Handle可以直接得到图片的句柄 IPicture *pIPict ...

  3. 利用COM组件IPicture读取jpg、gif、bmp图片文件数据和显示图片

    1.读取图片数据 函数原型:bool LoadImage(const char *pName, unsigned char *pBitData); 函数功能,读取pName指向的图片文件的位图数据 b ...

  4. .NET中操作IPicture、IPictureDisp

    .NET中操作IPicture.IPictureDisp的小随笔   [题外话] 最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口.调用仪器的时候需要传输图片,提供的接口里 ...

  5. 收藏:IPicture总结

    1.IPicture接口对象的创建方法1:直接通过文件创建LPCSTR szFileUrl; IPicture *pIPicture; OleLoadPicturePath(CComBSTR(szFi ...

  6. VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx

    尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...

  7. 【VS开发】IPicture在指定窗口绘制图

    1.利用IPicture接口加载.显示图片 IPicture接口管理一个图片对象和它的属性.图片对象提供对Bitmap Icon Metafile的语言不相关的抽象支持.图像对象的主要接口是IPict ...

  8. COM 组件基础——GUID 和 接口

    一.前言 书接上回,话说在 doc(Word) 复合文件中,已经解决了保存 xls(Excel) 数据的问题了.那么,接下来又要解决另一个问题:当 WORD 程序读取复合文件,遇到了 xls 数据的时 ...

  9. NPOI操作Excel辅助类

    /// <summary> /// NPOI操作excel辅助类 /// </summary> public static class NPOIHelper { #region ...

随机推荐

  1. 在 .pro里加入 QMAKE_CXXFLAGS += /MP 将并行编译,加快编译速度(姚冬的办法)

    但是只对VC编译器有效果. 另外还可以自己设置stdafx.h文件 http://www.zhihu.com/question/23045749

  2. MFC与Qt的内存管理

    最近在做MFC向Qt的移植,在内存管理方面遇到了很头疼的问题,虽然不知道问题到底出在哪,先了解下这两个库的内存管理方式.于是转载两篇关于内存管理的文章. 一. Qt内存管理: 在Qt的程序中经常会看到 ...

  3. 从Hello, world开始认识IL <第一篇>

    IL代码分析方法 Hello, world历史 .NET学习方法论 1.引言 1988年Brian W.Kernighan和Dennis M.Ritchie合著了软件史上的经典巨著<The C ...

  4. android fragment 跳到另一个fragment

    一共有4个fragment,分别是contact(联系人),friends(朋友),search(查找),more(更多).使用的都是同一个布局,每个fragment中都有四个内部按钮,可以切换到其他 ...

  5. 《编程珠玑》第二章 aha算法

    A题:给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数. 1.在文件中至少存在这样一个数? 2.如果有足够的内存,如何处理? 3.如果内存不足,仅可以用文件来进行 ...

  6. Linux系统编程(16)——正则表达式入门

    字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等等.字符串是0个或更多个字符的序列.文本也就是文字,字符串.说某个字符串匹配某个正则表达式,通常是指这个字符串里 ...

  7. Implement Hash Map Using Primitive Types

    A small coding test that I encountered today. Question Using only primitive types, implement a fixed ...

  8. IEEE发布2016年度编程语言排行榜

    C 语言占据榜首,但大数据类是最大赢家. IEEE Spectrum 的第三次"最受欢迎编程语言"交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum 使用多 ...

  9. 总结 XSS 与 CSRF 两种跨站攻击

    前言 在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了 ...

  10. jquery第二期:三个例子带你走进jquery

    jquery是完全支持css的,我们举个例子来看看使用jquery的方便之处,这功劳是属于选择器的: 例1: <!DOCTYPE html PUBLIC "-//W3C//DTD HT ...