原文地址: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;
}
}
|