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: [email protected]
//////////////////////////////////////////////////////////////////////
#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));
}