關於jpg繪製,查看網上的帖子都是使用 CreateFile 和ReadFile 組合 或者 CFile 類的方法 獲取jpg資源加載到內存中的! 但是,在使用fopen ,fread 這個標準c++函數組合讀取資源時候卻使得 OleLoadPicture(...) 初始化失敗,累累報錯,網上也是沒有正解,經過自己的對三種讀取方法的對比,終於看出了些許端倪。這雖然是不起眼的一個問題,但是對於如何將“jpg圖片流”或相機視頻流,整理成合理格式再繪製到屏幕上卻有着決定成敗的意義!下面看看代碼:
IPicture * m_pPct;
int LoadPct(CString pcFile)//圖片的實現方法
{
HANDLE hFile = CreateFile(pcFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
// 獲得文件大小
DWORD dwFileSize = GetFileSize(hFile, NULL); //有些偷懶了,初始化CreateFile 只爲了 獲得 圖片大小
LPVOID pvData = NULL;
// 分配全局內存,獲得內存句柄
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
// 鎖定內存,獲得內存指針
pvData = GlobalLock(hGlobal);
DWORD dwBytesRead = 0;
// 讀取文件 //向內存指針中存入內容;
CloseHandle(hFile);
////////////////////////////////////// ** 通過 CFile::Read(...) 讀取的pvData 其 strlen(pvData) ==4 這是關鍵。**
//CFile file;
// file.Open( "c://a2.jpg", CFile::modeRead | CFile::shareDenyNone ); // 讀入文件內容
// DWORD dwSize = file.GetLength();
// file.Read( pvData, dwSize );
// file.Close();
//////////////////////////////////////
FILE *pf = fopen( "c://a2.jpg" ,"rb" );
char * filebuff = new char[1024*1024];
/////通過CFile讀取經驗 得知 fread(XX,4,XX,XX) 只有以4個字節爲長度的文件才能被OleLoadPicture 正確解析 **關鍵**
fread( filebuff,4,dwFileSize,pf );
memcpy( pvData,filebuff,dwFileSize);
fclose( pf );
int ix = strlen( (const char*)filebuff );
GlobalUnlock(hGlobal);
LPSTREAM pstm = NULL;
//從內存數據創建IStream*
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
// 創建IPicture
if (!m_pPct)
{
m_pPct->Release();
}
// 從IStream接口中載入圖片到IPicture中
hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&m_pPct);
// 釋放IStream接口
pstm->Release();
return 1;
}
///////////////////////////////////////////////////////////////////////////////////////////
int CJpegDrawTempDlg::DrawPct()//函數的實現
{
if(m_pPct)
{
CWnd *pWnd;
CDC *pDvc;
CRect rc;
long hmWidth;
long hmHeight;
pWnd = GetDlgItem(IDC_STATIC);
pDvc = pWnd->GetDC();
m_pPct->get_Width(&hmWidth);
m_pPct->get_Height(&hmHeight);
pWnd -> GetClientRect(&rc);
// 拉伸顯示
m_pPct->Render(pDvc->GetSafeHdc(), 0, 0,
rc.Width(), rc.Height(), 0, hmHeight, hmWidth, -hmHeight, &rc);
UpdateData(FALSE);
return TRUE;
}
return FALSE;
}