圖片文件的存在形式並不總是文件形式,有時可能是內存塊、也有可能是字節流,比如保存於數據庫中的某一圖片,用GetChunk方法讀取出來後一般保存在一個預先分配的內存塊中,我們知道內存塊的首地址,內存塊的大小,要把這樣的圖片顯示出來,可以自己編寫函數按文件結構解析數據,但未免太麻煩,也是沒有意義的“製造輪子”的重複工作,不如用windows系統自帶的Ipicture的COM組件顯示圖片來得更簡便些。下面是核心代碼。技巧是把數據內存塊轉換成一個內存文件CMemFile,不必把圖片文件存儲成一個臨時文件再讀取。
#include <atlbase.h> #include <afxpriv2.h> void CIpicDlg::ShowPic() { CComQIPtr<IPicture>spIPicture; HRESULT m_hr; //unsigned char* pPictureData; //UINT nPictureSize; CRect rc; m_wndPic1.GetClientRect(&rc); CDC* pDC = m_wndPic1.GetDC(); if(m_pPictureData) { CMemFile memfile; memfile.Attach(m_pPictureData,m_nPictureSize); CArchive ar(&memfile, CArchive::load | CArchive::bNoFlushOnDelete); CArchiveStream arcstream(&ar); HRESULT hr = OleLoadPicture((IStream*)&arcstream, 0, FALSE, IID_IPicture, (void**)&spIPicture); ASSERT(SUCCEEDED(hr) && spIPicture); OLE_XSIZE_HIMETRIC hmWidth = 0; OLE_YSIZE_HIMETRIC hmHeight = 0; m_hr = spIPicture->get_Width(&hmWidth); ASSERT(SUCCEEDED(m_hr)); m_hr = spIPicture->get_Height(&hmHeight); ASSERT(SUCCEEDED(m_hr)); spIPicture->Render(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(), 0, hmHeight, hmWidth, -hmHeight, NULL); CSize sz(hmWidth,hmHeight); pDC->HIMETRICtoDP(&sz); } if (spIPicture) { spIPicture.Release(); } }
其中m_pPictureData爲圖片數據塊首地址,m_nPictureSize爲內存塊大小。
測試的VS2005的源代碼可以在此下載【】。