DibShow.cpp
上传用户:piaozanzhu
上传日期:2008-02-14
资源大小:212k
文件大小:7k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. /*
  2. BITMAPFILEHEADER   bf;
  3. BITMAPINFOHEADER   bi;
  4. BOOL LoadBmpFile (HWND hWnd,char *BmpFileName)
  5. {
  6. //文件句柄
  7. HFILE              hf; 
  8. //指向BITMAPINFOHEADER结构的指针
  9. LPBITMAPINFOHEADER lpImgData; 
  10. //指向逻辑调色板结构的指针
  11. LOGPALETTE         *pPal; 
  12. //指向RGBQUAD结构的指针
  13. LPRGBQUAD          lpRGB; 
  14. //用来保存设备中原来的调色板
  15. HPALETTE           hPrevPalette; 
  16. //设备句柄
  17. HDC                hDc; 
  18. //存储调色板的局部内存句柄
  19. HLOCAL             hPal; 
  20. //每一行的字节数
  21. DWORD     LineBytes;  
  22. //实际的图象数据占用的字节数
  23. DWORD    ImgSize;   
  24. //实际用到的颜色数 ,即调色板数组中的颜色个数
  25. DWORD             NumColors; 
  26. DWORD             i;
  27. if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){
  28. MessageBox(hWnd,"File c:\test.bmp not found!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  29. return FALSE; //打开文件错误,返回
  30. }
  31. //将BITMAPFILEHEADER结构从文件中读出,填写到bf中
  32. _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  33. //将BITMAPINFOHEADER结构从文件中读出,填写到bi中
  34. _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
  35.     
  36. //我们定义了一个宏 #define WIDTHBYTES(i)    ((i+31)/32*4)
  37. //上面曾经提到过,每一行的字节数必须是4的整倍数,
  38. //只要调用WIDTHBYTES(bi.biWidth*bi.biBitCount)就能完成这一换算
  39. //举一个例子,对于2色图,如果图象宽是31,则每一行需要31位存储,合3个字节加
  40. //7位,因为字节数必须是4的整倍数,所以应该是4,而此时的//biWidth=31,biBitCount=1,WIDTHBYTES(31*1)=4,和我们设想的一样。
  41. //再举一个256色的例子,如果图象宽是31,则每一行需要31个字节存储,因为字节数
  42. //必须是4的整倍数,所以应该是32,而此时//biWidth=31,biBitCount=8,WIDTHBYTES(31*8)=32,和我们设想的一样。你可以多举
  43. //几个例子来验证一下
  44. //LineBytes为每一行的字节数
  45. LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  46. //ImgSize为实际的图象数据占用的字节数
  47. ImgSize=(DWORD)LineBytes*bi.biHeight;
  48. //NumColors为实际用到的颜色数 ,即调色板数组中的颜色个数
  49. if(bi.biClrUsed!=0)
  50. NumColors=(DWORD)bi.biClrUsed; //如果bi.biClrUsed不为零,就是本图象实际           
  51. //用到的颜色数
  52. else //否则,用到的颜色数为2的biBitCount次方。
  53. switch(bi.biBitCount){
  54.         case 1:
  55.              NumColors=2;
  56.              break;
  57.          case 4:
  58.              NumColors=16;
  59.              break;
  60.          case 8:
  61.              NumColors=256;
  62.              break;
  63.          case 24:
  64.              NumColors=0; //对于真彩色图,没用到调色板
  65.              break;
  66.               default:
  67.                   //不处理其它的颜色数,认为出错。
  68.                   MessageBox(hWnd,"Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  69.                   _lclose(hf);
  70.                   return FALSE; //关闭文件,返回FALSE
  71.            }
  72. if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)))
  73. {
  74. //计算出的偏移量与实际偏移量不符,一定是颜色数出错
  75.      MessageBox(hWnd,"Invalid color numbers!","Error Message" ,MB_OK|MB_ICONEXCLAMATION);
  76.         _lclose(hf);
  77.         return FALSE; //关闭文件,返回FALSE
  78. }
  79. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
  80. //分配内存,大小为BITMAPINFOHEADER结构长度加调色板+实际位图数据
  81.    if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
  82. {
  83. //分配内存错误
  84.      MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);
  85.      _lclose(hf);
  86.          return FALSE; //关闭文件,返回FALSE
  87. }
  88.    //指针lpImgData指向该内存区
  89.    lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
  90.   
  91.    //文件指针重新定位到BITMAPINFOHEADER开始处
  92.    _llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);
  93.    //将文件内容读入lpImgData
  94.    _hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
  95.          +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
  96.    _lclose(hf); //关闭文件
  97.     
  98.    if(NumColors!=0) //NumColors不为零,说明用到了调色板
  99.    {                    
  100.      //为逻辑调色板分配局部内存,大小为逻辑调色板结构长度加NumColors个PALETTENTRY大小
  101.      hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
  102.     
  103. //指针pPal指向该内存区
  104.      pPal =(LOGPALETTE *)LocalLock(hPal);
  105. //填写逻辑调色板结构的头
  106.       pPal->palNumEntries = NumColors;
  107.       pPal->palVersion    = 0x300;
  108.      //lpRGB指向的是调色板开始的位置
  109. lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
  110. //填写每一项
  111. for (i = 0; i < NumColors; i++)
  112. {
  113. pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
  114. pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
  115. pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
  116. pPal->palPalEntry[i].peFlags=(BYTE)0;
  117. lpRGB++; //指针移到下一项
  118. }
  119. //产生逻辑调色板,hPalette是一个全局变量
  120. hPalette=CreatePalette(pPal);
  121. //释放局部内存
  122. LocalUnlock(hPal);
  123. LocalFree(hPal);
  124.     }
  125.     //获得设备上下文句柄
  126.     hDc=GetDC(hWnd);
  127.     if(hPalette) //如果刚才产生了逻辑调色板
  128.     {
  129.     //将新的逻辑调色板选入DC,将旧的逻辑调色板句柄保存在hPrevPalette
  130.     hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
  131.     RealizePalette(hDc);
  132.     }
  133.     //产生位图句柄
  134.     hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
  135.     (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  136.     (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
  137.     //将原来的调色板(如果有的话)选入设备上下文句柄
  138.     if(hPalette && hPrevPalette)            
  139.     {
  140.     SelectPalette(hDc,hPrevPalette,FALSE);
  141.     RealizePalette(hDc);
  142.     }
  143.     ReleaseDC(hWnd,hDc); //释放设备上下文
  144.     GlobalUnlock(hImgData); //解锁内存区
  145.     return TRUE; //成功返回
  146.  }
  147. */
  148. /* BOOL DIBShow(CFile* pFile)
  149.  {
  150. BITMAPFILEHEADER bmfHeader;
  151. LPBITMAPINFOHEADER lpBMIH;
  152. int nCount, nSize;
  153. try 
  154. {
  155. nCount = pFile->Read((LPVOID) &bmfHeader, sizeof(BITMAPFILEHEADER));
  156. if(nCount != sizeof(BITMAPFILEHEADER)) {
  157. throw new CException;
  158. }
  159. if(bmfHeader.bfType != 0x4d42) {
  160. throw new CException;
  161. }
  162. nSize = bmfHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
  163. lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];
  164. //nBmihAlloc = m_nImageAlloc = crtAlloc;
  165. nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table
  166. //ComputeMetrics();
  167. if(lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
  168. TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmapn");
  169. throw new CException;
  170. }
  171. DWORD dwSizeImage = lpBMIH->biSizeImage;
  172. if(dwSizeImage == 0) {
  173. DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;
  174. if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) {
  175. dwBytes++;
  176. }
  177. dwBytes *= 4;
  178. dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression
  179. }
  180. LPVOID lpvColorTable = (LPBYTE) lpBMIH + sizeof(BITMAPINFOHEADER);
  181. //ComputePaletteSize(m_lpBMIH->biBitCount);
  182. if((lpBMIH == NULL) || (lpBMIH->biClrUsed == 0)) {
  183. switch(lpBMIH->biBitCount) {
  184. case 1:
  185. m_nColorTableEntries = 2;
  186. break;
  187. case 4:
  188. m_nColorTableEntries = 16;
  189. break;
  190. case 8:
  191. m_nColorTableEntries = 256;
  192. break;
  193. case 16:
  194. case 24:
  195. case 32:
  196. m_nColorTableEntries = 0;
  197. break;
  198. default:
  199. ASSERT(FALSE);
  200. }
  201. }
  202. else {
  203. m_nColorTableEntries = m_lpBMIH->biClrUsed;
  204. }
  205. ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256)); 
  206. MakePalette();
  207. m_lpImage = (LPBYTE) new char[m_dwSizeImage];
  208. nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only
  209. }
  210. catch(CException* pe) 
  211. {
  212. AfxMessageBox("Read error");
  213. pe->Delete();
  214. return FALSE;
  215. }
  216. return TRUE;
  217.  }*/