|
MFC提供的CWnd只有默认加载BMP文件的接口,对JPG等图像是不支持的,而实际中经常需要用到非BMP的图片,在VC中加载.JPG格式的图片,有两种方法,用流对象加载和用IPicture接口加载。
IPicture *m_picture; OLE_XSIZE_HIMETRIC m_width; OLE_YSIZE_HIMETRIC m_height;
CString m_filename("D:\\009.jpg");//文件名
CFile m_file(m_filename,CFile::modeRead );
//获取文件长度 DWORD m_filelen = m_file.GetLength();
//在堆上分配空间 HGLOBAL m_hglobal = GlobalAlloc(GMEM_MOVEABLE,m_filelen);
LPVOID pvdata = NULL; //锁定堆空间,获取指向堆空间的指针 pvdata = GlobalLock(m_hglobal);
//将文件数据读区到堆中 m_file.ReadHuge(pvdata,m_filelen);
IStream* m_stream;
GlobalUnlock(m_hglobal);
//在堆中创建流对象 CreateStreamOnHGlobal(m_hglobal,TRUE,&m_stream);
//利用流加载图像 OleLoadPicture(m_stream,m_filelen,TRUE,IID_IPicture,(LPVOID*)&m_picture);
m_picture->get_Width(&m_width); m_picture->get_Height(&m_height);
CDC* dc = GetDC();
m_IsShow = TRUE; CRect rect; GetClientRect(rect); SetScrollRange(SB_VERT,0,(int)(m_height/26.45)-rect.Height()); SetScrollRange(SB_HORZ,0,(int)(m_width/26.45)-rect.Width());
m_picture->Render(*dc,1,50,(int)(m_width/26.45),(int)(m_height/26.45),0,m_height,m_width,-m_height,NULL);
以上代码是用创建流文件的方式加载,也可以加载.gif图片,但不能显示动画效果。 下面的代码则是用IPicture接口的方式来加载jpg图片(全屏显示图片)。 注意:这两段代码不能用在wince平台上,在wince上加载有另外的函数。
CString szFileName; szFileName.Empty(); szFileName = "D:\\84.jpg"; IStream *pStm; CFileStatus fstatus; CFile file; LONG cb; if (file.Open(szFileName,CFile::modeRead) && file.GetStatus(szFileName,fstatus) && ((cb = fstatus.m_size) != -1)) { HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,cb); LPVOID pvData =NULL; if (hGlobal != NULL) { pvData = GlobalLock(hGlobal); if (pvData != NULL) { file.ReadHuge(pvData,cb); GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal,TRUE,&pStm); } } } // HRESULT Render( HDC hdc, //渲染图像用的设备环境句柄 // long x, //在hdc上的水平坐标 // long y, //在hdc上的垂直坐标 // long cx, //图像宽度 // long cy, //图像高度 // OLE_XPOS_HIMETRIC xSrc, //在源图像上的水平偏移 // OLE_YPOS_HIMETRIC ySrc, //在源图像上的垂直偏移 // OLE_XSIZE_HIMETRIC cxSrc,//在源图像上水平拷贝的数量 // OLE_YSIZE_HIMETRIC cySrc,//在源图像上垂直拷贝的数量 // LPCRECT prcWBounds //指向目标图元设备环境句柄的指针); CComQIPtr<IPicture> m_picture; HRESULT hr = OleLoadPicture(pStm,0,false,IID_IPicture,(void**)&m_picture); long a,b; m_picture->get_Width(&a); m_picture->get_Height(&b); CSize sz(a,b); CDC *pdc = GetDlgItem(IDC_STATIC)->GetDC(); // CDC *pdc = GetDC(); // pdc->HIMETRICtoDP(&sz); CRect rect; GetClientRect(rect); // GetDlgItem(IDC_STATIC)->GetClientRect(&rect); m_picture->Render(*pdc,0,0,sz.cx,sz.cy,0,b,a,-b,&rect); m_picture->Render(*pdc,rect.left,rect.top,rect.Width(), rect.Height(),0,b,a,-b,&rect);
也可以用GDI+把图片转成.bmp文件再加载,在StdAfx.h中静态调用gdiplus.lib,即由编译系统完成对DLL的加载,应用程序结束时卸载DLL的编码。如下: #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #include "GdiPlus.h" using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib") #endif
2、在类的头文件中定义,以下成员变量,用来初始化GDI+的使用和结束使用。 GdiplusStartupInput m_gdiplusStartupInput; ULONG_PTR m_gdiplusToken;
3、在初始化函数中,初始化GDI+。如:在OnCreate()函数中加入初始化GDI+的函数: GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
4、对应的在OnDestroy()函数中加入结束GDI+使用的函数: GdiplusShutdown(m_gdiplusToken);
接着,就可以使用GDI+了,要实现要求的内容很容易,方法如下: 写一个如下的方法: HBITMAP ReturnHBITMAP(CString FileName)//FileName可能是bmp、dib、png、gif、jpeg/jpg、tiff、emf等文件的文件名 { Bitmap tempBmp(FileName.AllocSysString()) ; Color backColor; HBITMAP HBitmap; tempBmp.GetHBITMAP(backColor,&HBitmap); return HBitmap;
}
在WM5.0+VC8.0的环境下,还可以COM(组件)的方式加载图片,这种方法能加载的图片的格式比较全(.jpg,.png,.gif),在Windows CE Tools\wce500\Windows Mobile 5.0 Pocket PC SDK\Samples\CPP\Win32\Imaging例子中,用这个COM可以加载皮肤,有兴趣的朋友可以试一下。
|