IPicture

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));
}

来自:
http://blog.sina.com.cn/s/blog_4935ba3e010006oj.html
http://zhidao.baidu.com/question/43566997.html?si=4
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值