原文地址:http://www.cnblogs.com/zuollblog/archive/2010/04/21/1716983.html
1.讀取圖片數據
函數原型:bool LoadImage(const char *pName, unsigned char *pBitData);
函數功能,讀取pName指向的圖片文件的位圖數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
bool LoadImage( const char *pName,
unsigned char *pBitData)
{ HDC hdcTemp; //
DC用來保存位圖 HBITMAP hbmpTemp; //
保存臨時位圖 IPicture *pPicture; // 定義IPicture Interface OLECHAR wszPath[MAX_PATH+1]; // 圖片的完全路徑 char szPath[MAX_PATH+1]; //
圖片的完全路徑 long lWidth; //
圖像寬度 long lHeight; //
圖像高度 long lWidthPixels; //
圖像的寬帶(以像素爲單位) long lHeightPixels; //
圖像的高帶(以像素爲單位) GLint glMaxTexDim ; // 保存紋理的最大尺寸 { strcpy (szPath, pName); //
把路徑拷貝到 szPath } else // 否則從文件導入圖片
{ GetCurrentDirectory(MAX_PATH, szPath); // 取得當前路徑
strcat (szPath, "\\" ); //
添加字符"\" strcat (szPath, pName); //
添加圖片的相對路徑 } MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); // 把ASCII碼轉化爲Unicode標準碼 HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, ( void **)&pPicture); if (FAILED(hr)) // 如果導入失敗
{ // 圖片載入失敗出錯信息 MessageBox (HWND_DESKTOP, "圖片導入失敗!\n(TextureLoad Failed!)" , "Error" ,
MB_OK | MB_ICONEXCLAMATION); return FALSE;
// 返回 FALSE } hdcTemp = CreateCompatibleDC(GetDC(0)); // 建立窗口設備描述表
if (!hdcTemp) // 建立失敗?
{ pPicture->Release(); // 釋放IPicture
// 圖片載入失敗出錯信息 MessageBox (HWND_DESKTOP, "圖片導入失敗!\n(TextureLoad Failed!)" , "Error" ,
MB_OK | MB_ICONEXCLAMATION); return FALSE;
// 返回 FALSE } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); // 取得支持的紋理最大尺寸
pPicture->get_Width(&lWidth); // 取得IPicture 寬度 (轉換爲Pixels格式) lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); // 取得IPicture 高度 (轉換爲Pixels格式) lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); // 調整圖片到最好的效果 if (lWidthPixels <= glMaxTexDim)
// 圖片寬度是否超過顯卡最大支持尺寸 lWidthPixels = 1 << ( int ) floor (( log (( double )lWidthPixels)/ log (2.0f))
+ 0.5f); else // 否則,將圖片寬度設爲顯卡最大支持尺寸
lWidthPixels = glMaxTexDim; if (lHeightPixels <= glMaxTexDim)
// 圖片高度是否超過顯卡最大支持尺寸 lHeightPixels = 1 << ( int ) floor (( log (( double )lHeightPixels)/ log (2.0f))
+ 0.5f); else // 否則,將圖片高度設爲顯卡最大支持尺寸
lHeightPixels = glMaxTexDim; // 建立一個臨時位圖
BITMAPINFO bi = {0}; // 位圖的類型
DWORD *pBits = 0;
// 指向位圖Bits的指針 bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); //
設置結構大小 bi.bmiHeader.biBitCount = 32; // 32 位
bi.bmiHeader.biWidth = lWidthPixels; // 寬度像素值
bi.bmiHeader.biHeight = lHeightPixels; // 高度像素值
bi.bmiHeader.biCompression = BI_RGB; // RGB 格式
bi.bmiHeader.biPlanes = 1; // 一個位平面
// 建立一個位圖這樣我們可以指定顏色和深度 並訪問每位的值 hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, ( void **)&pBits,
0, 0); if (!hbmpTemp) // 建立失敗?
{ DeleteDC(hdcTemp); // 刪除設備描述表
pPicture->Release(); // 釋放IPicture
// 圖片載入失敗出錯信息 MessageBox (HWND_DESKTOP, "圖片導入失敗!\n(TextureLoad Failed!)" , "Error" ,
MB_OK | MB_ICONEXCLAMATION); return FALSE;
// 返回 FALSE } SelectObject(hdcTemp, hbmpTemp); //選擇臨時DC句柄和臨時位圖對象
// 在位圖上繪製IPicture pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); // 將BGR轉換爲RGB 將ALPHA值設爲255 width = lWidthPixels; height = lHeightPixels; pBitData = new unsigned
char [lWidthPixels * lHeightPixels * 4]; // 循環遍歷所有的像素 for ( long i
= 0; i < lWidthPixels * lHeightPixels; i++) { BYTE * pPixel = ( BYTE *)(&pBits[i]); //
獲取當前像素 pBitData[i*4] = pPixel[2]; pBitData[i*4+1] = pPixel[1]; pBitData[i*4+2] = pPixel[0]; pBitData[i*4+3] = 255; } DeleteObject(hbmpTemp); // 刪除對象
DeleteDC(hdcTemp); // 刪除設備描述表
pPicture->Release(); // 釋放 IPicture
return true ; //
返回 TRUE } |
2.顯示圖片
函數原型:HRESULT ShowPicture(CString lpImageFile, HWND hWnd, int nScrWidth, int nScrHeight)
函數功能,讀取lpImageFile指向的圖片文件,並且顯示以nScrWidth*nScrHeight顯示在hWnd中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
HRESULT ShowPicture(CString lpImageFile,
HWND hWnd,
int nScrWidth,
int nScrHeight)
{ HDC hDC_Temp=::GetDC(hWnd);
IPicture *pPic; IStream *pStm; BOOL bResult;
HANDLE hFile=NULL;
DWORD dwFileSize,dwByteRead;
//打開硬盤中的圖形文件 hFile=CreateFile(lpImageFile,GENERIC_READ, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile!=INVALID_HANDLE_VALUE)
{ dwFileSize=GetFileSize(hFile,NULL); //獲取文件字節數 if (dwFileSize==0xFFFFFFFF)
return E_FAIL;
} else { return E_FAIL;
} //分配全局存儲空間 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
LPVOID pvData = NULL;
if (hGlobal == NULL)
{ AfxMessageBox(_T( "圖片分配內存出錯!" )); return E_FAIL;
} if ((pvData = GlobalLock(hGlobal)) == NULL) //鎖定分配內存塊 { AfxMessageBox(_T( "內存塊鎖定出問題!" )); return E_FAIL;
} ReadFile(hFile, pvData, dwFileSize, &dwByteRead, NULL); //把文件讀入內存緩衝區 GlobalUnlock(hGlobal); if (CreateStreamOnHGlobal(hGlobal, TRUE, &pStm) != S_OK) { AfxMessageBox(_T( "流初始化失敗!" )); return E_FAIL;
} //裝入圖形文件 bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,( LPVOID *)&pPic); if (FAILED(bResult)) { AfxMessageBox(_T( "圖形文件裝載出錯!" )); return E_FAIL;
} OLE_XSIZE_HIMETRIC hmWidth; //圖片的真實寬度 OLE_YSIZE_HIMETRIC hmHeight; //圖片的真實高度 pPic->get_Width(&hmWidth); pPic->get_Height(&hmHeight); //將圖形輸出到屏幕上 bResult=pPic->Render(hDC_Temp,0,0,nScrWidth,nScrHeight, 0,hmHeight,hmWidth,-hmHeight,NULL); CloseHandle(hFile); //關閉打開的文件 pPic->Release(); // Free memory. GlobalFree(hGlobal); if (SUCCEEDED(bResult))
{ return S_OK;
} else { AfxMessageBox(_T( "圖形文件裝載出錯!" )); return E_FAIL;
} } |