文档库 最新最全的文档下载
当前位置:文档库 › 加入JPG图片1陈

加入JPG图片1陈


/////////////////////////////////////////////////////////////////////////////
// CIm4View drawing

void CIm4View::OnDraw(CDC* pDC)
{



::CoInitialize(NULL); // COM 初始化
HRESULT hr;
CFile file;

file.Open( "D:\\aa.jpg ", CFile::modeRead | CFile::shareDenyNone ); // 读入文件内容 文件路径D:\\aa.jpg
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 ); // 高
/*
////////原大显示//////
CSize sz( nWidth, nHeight );
pDC->HIMETRICtoDP( &sz ); // 转换 MM_HIMETRIC 模式单位为 MM_TEXT 像素单位
pPicture->Render(pDC->m_hDC,0,0,sz.cx,sz.cy,0,nHeight,nWidth,-nHeight,NULL);
*/
////////按窗口尺寸显示////////
CRect rect; GetClientRect(&rect);
pPicture->Render(pDC->m_hDC,0,0,rect.Width(),rect.Height(),0,nHeight,nWidth,-nHeight,NULL);

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

::CoUninitialize();
}























关于IPicture::Render函数



1、IPicture::Render简介

HRESULT Render(
HDC hdc, //Handle of device context on which to render the image
long x, //Horizontal position of image in hdc
long y, //Vertical position of image in hdc
long cx, //Horizontal dimension of destination rectangle
long cy, //Vertical dimension of destination rectangle
OLE_XPOS_HIMETRIC xSrc,
//Horizontal offset in source picture
OLE_YPOS_HIMETRIC ySrc,
//Vertical offset in source picture
OLE_XSIZE_HIMETRIC cxSrc,
//Amount to copy horizontally in source picture
OLE_YSIZE_HIMETRIC cySrc,
//Amount to copy vertically in source picture
LPCRECT prcWBounds
//Pointer to position )

x,y,cx,cy分别是指在屏幕上显示的左上角和右下角;

xsrc,ysrc,cxsrc,cysrc分别是指图片的大小,所以屏幕上长宽的比例和图片长宽的比例是一样的。

有一点令人不解 0,hmHeight,hmWidth,-hmHeight对应于xsrc,ysrc,cxsrc,cysrc,并不是以0,0开头。prcWBounds 一般赋值为NULL。

2、IPicture::Render其它说明

网上观点一:

在做一个图片浏览控件,用Render显示JPG图片,并能拖动图片(调整左上坐标),当图片是原图大小时,拖动的时候速度很快,但当缩小或放大图片后再拖动,速度就非

常慢了


m_spIPicture->Render(*pDC, lOffsetX, lOffsetY, lWidth, lHeight,
0 , hmHeight, hmWidth, -hmHeight, 0);

也就是当lWidth和lHeight不等于原图大小时,调整lOffsetX或lOffsetY,Render执行比较慢。


不知道我有没有把问题说清楚。

网上观点二:

嗯,GDI+速度还可以,但是拖动之前保存一个缩略图,拖动中不显示原始图片而显示一个带缩略图的图标(就像在资源管理器中拖动文件那样)比较好一点。

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

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

















































添加一个picture控件类型设为Bitmap,选好图像,就可以显示了。初始显示在按钮之上,按下按钮后,变为之下。

一 控件适应于图片尺寸

添加一个picture控件,修改ID为IDC_PICTURE,并添加一成员变量
CBitmap m_bmp;

在OnInitDialog()函数中添加如下代码
if(m_bmp.m_hObject!=NULL) m_bmp.DeleteObject();
//以绝对路径加载BMP图片eg2.bmp
HBITMAP hbmp=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),"eg2.bmp",IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if(hbmp==NULL)
return false;
//获得加载位图的文件信息
m_bmp.Attach(hbmp);
DIBSECTION ds;
BITMAPINFOHEADER &bminfo=ds.dsBmih;//获得位图信息图
m_bmp.GetObject(sizeof(ds),&ds);
int cx=bminfo.biWidth;//获得位图宽度
int cy=bminfo.biHeight;//获得位图高度
//该段程序根据图象的宽和高,调整控件大小,让它正好显示一张图片
CRect rect;
GetDlgItem(IDC_PICTURE)->GetWindowRect(&rect);//获得控件所在矩形区域
ScreenToClient(&rect);
GetDlgItem(IDC_PICTURE)->MoveWindow(rect.left,rect.top,cx,cy,true);//调整控件大小


在OnPaint()函数中添加如下代码
//三种方法获得pictrue控件DC,图象将被绘制在控件上
CPaintDC dc(GetDlgItem(IDC_PICTURE));
//CPaintDC dc(this);
//CDC dc;
//dc.m_hDC=::GetDC(NULL);

CRect rcclient;
GetDlgItem(IDC_PICTURE)->GetClientRect(&rcclient);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,rcclient.Width(),rcclient.Height());
memdc.SelectObject(&bitmap);

CWnd::DefWindowProc(WM_PAINT,(WPARAM)memdc.m_hDC,0);
CDC maskdc;
maskdc.CreateCompatibleDC(&dc);
CBitmap maskbitmap;
maskbitmap.CreateBitmap(rcclient.Width(),rcclient.Height(),1,1,NULL);
maskdc.SelectObject(&maskbitmap);
maskdc.BitBlt(0,0,rcclient.Width(),rcclient.Height(),&memdc,rcclient.left,rcclient.top,SRCCOPY);

CBrush brush;
brush.CreatePatternBrush(&m_bmp);
dc.FillRect(rcclient,&brush);
dc.BitBlt(rcclient.left,rcclient.top,rcclient.Width(),rcclient.Height(),&memdc,
rcclient.left,rcclient.top,SRCPAINT);
brush.DeleteObject();

二 图片适用于控件尺寸
添加一个picture控件,修改ID为IDC_PICTURE1,在目录中存图片RF_view.jpg,
在OnPaint()函数中添加如下代码(如需要无边框,可将类型设为Bitmap)


CWnd *pWnd=GetDlgItem(IDC_PICTURE1);//获得pictrue控件窗口的句柄
CRect rect;
pWnd->GetClientRect(&rect);//获得pictrue控件所在的举行区域
CDC *pDC=pWnd->GetDC();//

获得pictrue控件的DC

IStream *pStm;
CFileStatus fstatus;
CFile file;
LONG cb;

IPicture *pPic;//定义显示图片的接口(可显示jpg格式图片)
CString m_sPath="RF_view.jpg";//设置想要显示的图片
//打开图象文件,获取文件字节数
if(file.Open(m_sPath,CFile::modeRead) && file.GetStatus(m_sPath,fstatus)
&& ((cb=fstatus.m_size)!=-1))
{
//分配全局存储空间
HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,cb);
LPVOID pvData=NULL;
if(hGlobal!=NULL)
{
//锁定分配内存块
if((pvData=GlobalLock(hGlobal))!=NULL)
{
//读入文件到内存缓冲区
file.ReadHuge(pvData,cb);
GlobalUnlock(hGlobal);
CreateStreamOnHGlobal(hGlobal,true,&pStm);
}
}
}

//装载图象文件
if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)))
{
OLE_XSIZE_HIMETRIC hmWidth;
OLE_XSIZE_HIMETRIC hmHeight;
pPic->get_Width(&hmWidth);//获得图象真实宽度
pPic->get_Height(&hmHeight);//获得图象真实高度
//在控件上显示图片
pPic->Render(*pDC,0,0,rect.Width(),rect.Height(),0,hmHeight,hmWidth,-hmHeight,NULL);
pPic->Release();
}



防止闪屏,即在OnCtlColor里将背景设为透明即可

HBRUSH CeGuangView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here
pDC->SetBkMode(TRANSPARENT); //设置背景透明
pDC->SetTextColor(RGB(255,0,0)); //改变字体的颜色
return HBRUSH(GetStockObject(HOLLOW_BRUSH));


// TODO: Return a different brush if the default is not desired
return hbr;
}













,只要在OnPaint里面加以下代码
void CRFformView::OnPaint()
{
CPaintDC dc(this);
// device context for painting

// standard paint routine

OnPrepareDC(&dc);
OnDraw(&dc);






相关文档
相关文档 最新文档