利用COM组件IPicture读取jpg、gif、bmp图片文件数据和显示图片的两个函数
Posted on 2010-04-21 11:08 3DDreams 阅读(4070) 评论(0) 编辑 收藏 举报1.读取图片数据
函数原型:bool LoadImage(const char *pName, unsigned char *pBitData);
函数功能,读取pName指向的图片文件的位图数据
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 ; // 保存纹理的最大尺寸 if (strstr(pName, "http://")) // 如果路径包含 http:// 则... { 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中
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; } }