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));
}
IPicture总结的更多相关文章
- .NET中操作IPicture、IPictureDisp的小随笔
[题外话] 最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口.调用仪器的时候需要传输图片,提供的接口里使用了IPicture这个接口,由于以前没接触过,所以查找了一些资料, ...
- IPicture、BITMAP、HBITMAP和CBitmap的关系
1.有关IPicture加载图片后直接Render到内存DC的问题(HBITMAP转换IPicture)Picture的方法get_Handle可以直接得到图片的句柄 IPicture *pIPict ...
- 利用COM组件IPicture读取jpg、gif、bmp图片文件数据和显示图片
1.读取图片数据 函数原型:bool LoadImage(const char *pName, unsigned char *pBitData); 函数功能,读取pName指向的图片文件的位图数据 b ...
- .NET中操作IPicture、IPictureDisp
.NET中操作IPicture.IPictureDisp的小随笔 [题外话] 最近在做一个调用某实验仪器的程序,这个仪器提供了Windows上COM的接口.调用仪器的时候需要传输图片,提供的接口里 ...
- 收藏:IPicture总结
1.IPicture接口对象的创建方法1:直接通过文件创建LPCSTR szFileUrl; IPicture *pIPicture; OleLoadPicturePath(CComBSTR(szFi ...
- VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx
尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...
- 【VS开发】IPicture在指定窗口绘制图
1.利用IPicture接口加载.显示图片 IPicture接口管理一个图片对象和它的属性.图片对象提供对Bitmap Icon Metafile的语言不相关的抽象支持.图像对象的主要接口是IPict ...
- COM 组件基础——GUID 和 接口
一.前言 书接上回,话说在 doc(Word) 复合文件中,已经解决了保存 xls(Excel) 数据的问题了.那么,接下来又要解决另一个问题:当 WORD 程序读取复合文件,遇到了 xls 数据的时 ...
- NPOI操作Excel辅助类
/// <summary> /// NPOI操作excel辅助类 /// </summary> public static class NPOIHelper { #region ...
随机推荐
- 《how to design programs》第11章自然数
这章让我明白了原来自然数的定义本来就是个递归的过程. 我们通常用枚举的方式引出自然数的定义:0,1,2,3,等等(etc).最后的等等是什么意思?唯一能把等等从描述自然数的枚举方法中去除的方法是自引用 ...
- JAVA的类加载器,详细解释
JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader). 一. ClassLoader基本概念 1.ClassL ...
- 剑指offer-面试题11.数值的整数次方
题目:实现函数double Power(double base,int exponent),求base的 exponent次方.不得使用库函数,同时不需要考虑大数的问题. 这道题看似很简单: 然而需要 ...
- HDOJ-1018 Big Number
http://acm.hdu.edu.cn/showproblem.php?pid=1018 题意:给出一个数n,输出n的阶乘的位数 汗Σ( ° △ °|||)︴刚开始还准备上大数乘法 然而10000 ...
- SHDP--Working With HBase (二)之HBase JDBC驱动Phoenix与SpringJDBCTemplate的集成
Phoenix:Phoenix将SQL查询语句转换成多个scan操作,并编排执行最终生成标准的JDBC结果集. Spring将数据库访问的样式代码提取到JDBC模板类中,JDBC模板还承担了资源管 ...
- Struts2使用Interceptor实现权限控制的应用实例详解
Struts2使用Interceptor实现权限控制的应用实例详解 拦截器:是Struts2框架的核心,重点之重.因此,对于我们要向彻底学好Struts2.0.读源码和使用拦截器是必不可少的.少说了. ...
- 让浏览器非阻塞加载javascript的几种方式
通常大多数浏览器是并行下载资源的,但由于外部脚本的特殊性例如通过脚本改变文档的DOM结构.脚本之间的存在依赖关系.使用document.write 向页面输出HTML等.浏览器为了确保正确执行脚本和呈 ...
- Ubuntu亮度无法调节或调节无法保存的问题
装了搜狗输入法之后,系统设置里面的很多软件都没有了.以前屏幕太亮在电源里面可以调节,现在不行了.没办法,只能找其他的办法了. 在网上查了很多资料,经自己的实验,找到了一个成功的方法. 首先进入 /sy ...
- SqlBulkCopy使用介绍以及注意事项
SqlBulkCopy,微软提供的快速插入类,针对大批量数据操作,此类效果明显有所提升,以下是微软官方解释: Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具 ...
- photoswipe
allowUserZoom: 允许用户双击放大/移动方式查看图片. 默认值 = trueautoStartSlideshow: 当PhotoSwipe激活后,自动播放幻灯片. 默认值 = falsea ...