图片文件的存在形式并不总是文件形式,有时可能是内存块、也有可能是字节流,比如保存于数据库中的某一图片,用GetChunk方法读取出来后一般保存在一个预先分配的内存块中,我们知道内存块的首地址,内存块的大小,要把这样的图片显示出来,可以自己编写函数按文件结构解析数据,但未免太麻烦,也是没有意义的“制造轮子”的重复工作,不如用windows系统自带的Ipicture的COM组件显示图片来得更简便些。下面是核心代码。技巧是把数据内存块转换成一个内存文件CMemFile,不必把图片文件存储成一个临时文件再读取。
1 #include <atlbase.h>
2 #include <afxpriv2.h>
3 void CIpicDlg::ShowPic()
4 {
5 CComQIPtr<IPicture>spIPicture;
6 HRESULT m_hr;
7 //unsigned char* pPictureData;
8 //UINT nPictureSize;
9 CRect rc;
10 m_wndPic1.GetClientRect(&rc);
11 CDC* pDC = m_wndPic1.GetDC();
12 if(m_pPictureData)
13 {
14 CMemFile memfile;
15 memfile.Attach(m_pPictureData,m_nPictureSize);
16 CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete);
17 CArchiveStream arcstream(&ar);
18 HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE,
19 IID_IPicture, (void**)&spIPicture);
20 ASSERT(SUCCEEDED(hr) && spIPicture);
21 OLE_XSIZE_HIMETRIC hmWidth = 0;
22 OLE_YSIZE_HIMETRIC hmHeight = 0;
23 m_hr = spIPicture->get_Width(&hmWidth);
24 ASSERT(SUCCEEDED(m_hr));
25 m_hr = spIPicture->get_Height(&hmHeight);
26 ASSERT(SUCCEEDED(m_hr));
27 spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
28 0, hmHeight, hmWidth, -hmHeight, NULL);
29 CSize sz(hmWidth,hmHeight);
30 pDC->HIMETRICtoDP(&sz);
31 }
32 if (spIPicture)
33 {
34 spIPicture.Release();
35 }
36 }
3 void CIpicDlg::ShowPic()
4 {
5 CComQIPtr<IPicture>spIPicture;
6 HRESULT m_hr;
7 //unsigned char* pPictureData;
8 //UINT nPictureSize;
9 CRect rc;
10 m_wndPic1.GetClientRect(&rc);
11 CDC* pDC = m_wndPic1.GetDC();
12 if(m_pPictureData)
13 {
14 CMemFile memfile;
15 memfile.Attach(m_pPictureData,m_nPictureSize);
16 CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete);
17 CArchiveStream arcstream(&ar);
18 HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE,
19 IID_IPicture, (void**)&spIPicture);
20 ASSERT(SUCCEEDED(hr) && spIPicture);
21 OLE_XSIZE_HIMETRIC hmWidth = 0;
22 OLE_YSIZE_HIMETRIC hmHeight = 0;
23 m_hr = spIPicture->get_Width(&hmWidth);
24 ASSERT(SUCCEEDED(m_hr));
25 m_hr = spIPicture->get_Height(&hmHeight);
26 ASSERT(SUCCEEDED(m_hr));
27 spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(),
28 0, hmHeight, hmWidth, -hmHeight, NULL);
29 CSize sz(hmWidth,hmHeight);
30 pDC->HIMETRICtoDP(&sz);
31 }
32 if (spIPicture)
33 {
34 spIPicture.Release();
35 }
36 }
其中m_pPictureData为图片数据块首地址,m_nPictureSize为内存块大小。
测试的VS2005的源代码可以在此下载【】。