void     GrayConversionXu(HDIB&   hDib)  
  {  
  HDIB   hGreyDIB=NULL;  
  DWORD   nWide,nHeight,i,j;  
  LPBYTE   lpBit=(LPBYTE)GlobalLock(hDib);  
  LPBITMAPINFOHEADER   pHeader=(LPBITMAPINFOHEADER)lpBit;  
  nWide=pHeader->biWidth;  
  nHeight=pHeader->biHeight;  
  DWORD   dGrayDIBSize;  
  if(IS_WIN30_DIB(lpBit))  
  dGrayDIBSize=pHeader->biSize+256*sizeof(RGBQUAD)+(nWide*8+31)/32*4*nHeight;  
  else  
  dGrayDIBSize=pHeader->biSize+256*sizeof(RGBTRIPLE)+(nWide*8+31)/32*4*nHeight;  
  hGreyDIB=(HDIB)GlobalAlloc(GHND,dGrayDIBSize);  
  LPBITMAPINFO   lpGray=(LPBITMAPINFO)GlobalLock(hGreyDIB);  
  lpGray->bmiHeader=*pHeader;  
  lpGray->bmiHeader.biBitCount=8;  
  if(IS_WIN30_DIB(lpBit))  
  for(i=0;i<256;i++)  
  {  
  lpGray->bmiColors[i].rgbBlue=(BYTE)i;  
  lpGray->bmiColors[i].rgbGreen=(BYTE)i;  
  lpGray->bmiColors[i].rgbRed=(BYTE)i;  
  lpGray->bmiColors[i].rgbReserved=(BYTE)0;  
  }  
  else  
  for(i=0;i<256;i++)  
  {  
  lpGray->bmiColors[i].rgbBlue=(BYTE)i;  
  lpGray->bmiColors[i].rgbGreen=(BYTE)i;  
  lpGray->bmiColors[i].rgbRed=(BYTE)i;  
  }  
  LPBYTE   lpGrayBit=(LPBYTE)lpGray;  
   
  if(IS_WIN30_DIB(lpBit))  
  lpGrayBit+=pHeader->biSize+256*sizeof(RGBQUAD);  
  else  
  lpGrayBit+=pHeader->biSize+256*sizeof(RGBTRIPLE);  
  int   nCountBit=pHeader->biBitCount;  
   
  if(nCountBit>8)  
  {  
  lpBit+=sizeof(BITMAPINFOHEADER);  
  int   nRGB=(nWide*nCountBit+31)/32*4-nWide*nCountBit/8;  
  int   nGrey=(nWide*8+31)/32*4-nWide;  
  for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
          *lpGrayBit++=(*lpBit++)*0.299+(*lpBit++)*0.587+(*lpBit++)*0.114;  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
          ::GlobalUnlock((HGLOBAL)hDib);  
  ::GlobalFree((HGLOBAL)hDib);  
  hDib   =   hGreyDIB;  
  ::GlobalUnlock((HGLOBAL)hGreyDIB);  
  }  
   
   
  else  
  {  
  DWORD   nColorCount=1<<nCountBit;  
  BYTE pGreyTable[256];  
  RGBQUAD pDIBColors[256];  
  LPBITMAPINFO   lpBitmapinfo=(LPBITMAPINFO)lpBit;  
  for(i=0;i<nColorCount;i++)  
  {        
  if(IS_WIN30_DIB(lpBit))  
  {  
  pDIBColors[i].rgbBlue=lpBitmapinfo->bmiColors[i].rgbBlue;  
  pDIBColors[i].rgbGreen=lpBitmapinfo->bmiColors[i].rgbGreen;  
  pDIBColors[i].rgbRed=lpBitmapinfo->bmiColors[i].rgbRed;  
  pDIBColors[i].rgbReserved=lpBitmapinfo->bmiColors[i].rgbReserved;  
  }  
  else  
  {  
          pDIBColors[i].rgbBlue=lpBitmapinfo->bmiColors[i].rgbBlue;  
  pDIBColors[i].rgbGreen=lpBitmapinfo->bmiColors[i].rgbGreen;  
  pDIBColors[i].rgbRed=lpBitmapinfo->bmiColors[i].rgbRed;  
  }  
        pGreyTable[i]=pDIBColors[i].rgbBlue*0.114+pDIBColors[i].rgbRed*0.299+pDIBColors[i].rgbGreen*0.587;  
  }  
  lpBit=lpBit+sizeof(BITMAPINFOHEADER)+PaletteSize(lpBit);  
  int   nRGB=(nWide*nCountBit+31)/32*4-(nWide*nCountBit)/8;  
  int   nGrey=(nWide*8+31)/32*4-nWide;  
  switch(nColorCount)  
  {  
  case   2:  
    for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  {  
  BYTE   n=1<<(7-j%8);  
  BYTE   Temp=*(BYTE*)lpBit;  
  Temp&=n;  
            *lpGrayBit++=pGreyTable[Temp>>(7-j%8)];  
    if((j+1)%8==0)lpBit++;  
  }  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
   
  break;  
  case     16:  
    for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  {  
   
  BYTE   Temp=*lpBit;  
  BYTE   n=j%2   ?0x0f:0xf0;  
  Temp&=n;  
  Temp=Temp>>(j%2   ?0:4);  
                  *lpGrayBit++=pGreyTable[Temp];  
  if((j+1)%2==0)lpBit++;  
  }  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
  break;  
  case   256:  
          for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  *lpGrayBit++=pGreyTable[(*lpBit++)];  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
   
  break;  
  }  
  ::GlobalUnlock((HGLOBAL)hDib);  
  ::GlobalFree((HGLOBAL)hDib);  
    hDib   =   hGreyDIB;  
  ::GlobalUnlock((HGLOBAL)hGreyDIB);  
  }  
  }
加了注释后
void     GrayConversionXu(HDIB&   hDib)  
  {  
  //预备生成空白的DIB以保存灰度图像  
  HDIB   hGreyDIB=NULL;  
  DWORD   nWide,nHeight,i,j;  
   
  //读取原DIB中的有关信息以取得生成的DIB需要多大的空间  
  LPBYTE   lpBit=(LPBYTE)GlobalLock(hDib);  
  LPBITMAPINFOHEADER   pHeader=(LPBITMAPINFOHEADER)lpBit;  
  nWide=pHeader->biWidth;  
  nHeight=pHeader->biHeight;  
  DWORD   dGrayDIBSize;  
   
  if(IS_WIN30_DIB(lpBit))  
  dGrayDIBSize=pHeader->biSize+256*sizeof(RGBQUAD)+(nWide*8+31)/32*4*nHeight;  
  else  
  dGrayDIBSize=pHeader->biSize+256*sizeof(RGBTRIPLE)+(nWide*8+31)/32*4*nHeight;  
  //上面是计算所占空间的,头部+色表+像素部分  
  hGreyDIB=(HDIB)GlobalAlloc(GHND,dGrayDIBSize);  
   
  //颜色表初始化  
  LPBITMAPINFO   lpGray=(LPBITMAPINFO)GlobalLock(hGreyDIB);  
  lpGray->bmiHeader=*pHeader;  
  lpGray->bmiHeader.biBitCount=8;  
  if(IS_WIN30_DIB(lpBit))  
  for(i=0;i<256;i++)  
  {  
  lpGray->bmiColors[i].rgbBlue=(BYTE)i;  
  lpGray->bmiColors[i].rgbGreen=(BYTE)i;  
  lpGray->bmiColors[i].rgbRed=(BYTE)i;  
  lpGray->bmiColors[i].rgbReserved=(BYTE)0;  
  }  
  else  
  for(i=0;i<256;i++)  
  {  
  lpGray->bmiColors[i].rgbBlue=(BYTE)i;  
  lpGray->bmiColors[i].rgbGreen=(BYTE)i;  
  lpGray->bmiColors[i].rgbRed=(BYTE)i;  
  }  
  LPBYTE   lpGrayBit=(LPBYTE)lpGray;  
  //上面的是定义了一个指针目前指向DIB的头部吧  
   
  if(IS_WIN30_DIB(lpBit))  
  lpGrayBit+=pHeader->biSize+256*sizeof(RGBQUAD);  
  else  
  lpGrayBit+=pHeader->biSize+256*sizeof(RGBTRIPLE);  
  加上偏移就指向了像素的地址了.  
  int   nCountBit=pHeader->biBitCount;  
  色彩的位数  
  if(nCountBit>8)  
  {  
  lpBit+=sizeof(BITMAPINFOHEADER);  
  //一条扫描线一条扫描线的进行处理的.  
  //下面的两个变量可能是一个偏移主要可能是24位可能不要偏移,32位还有一个8位的偏移  
  int   nRGB=(nWide*nCountBit+31)/32*4-nWide*nCountBit/8;  
  int   nGrey=(nWide*8+31)/32*4-nWide;  
  for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
          *lpGrayBit++=(*lpBit++)*0.299+(*lpBit++)*0.587+(*lpBit++)*0.114;  
  //上面这句可以看出楼主可能优化方面做得不好请看相关的优化部分,用了浮点运算是个很大的错误.  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
          ::GlobalUnlock((HGLOBAL)hDib);  
  ::GlobalFree((HGLOBAL)hDib);  
  hDib   =   hGreyDIB;  
  ::GlobalUnlock((HGLOBAL)hGreyDIB);  
  }  
  //上面是对256以上色的处理  
  else  
  {  
  DWORD   nColorCount=1<<nCountBit;  
  BYTE pGreyTable[256];  
  RGBQUAD pDIBColors[256];  
  LPBITMAPINFO   lpBitmapinfo=(LPBITMAPINFO)lpBit;  
  for(i=0;i<nColorCount;i++)  
  {        
  if(IS_WIN30_DIB(lpBit))  
  {  
  pDIBColors[i].rgbBlue=lpBitmapinfo->bmiColors[i].rgbBlue;  
  pDIBColors[i].rgbGreen=lpBitmapinfo->bmiColors[i].rgbGreen;  
  pDIBColors[i].rgbRed=lpBitmapinfo->bmiColors[i].rgbRed;  
  pDIBColors[i].rgbReserved=lpBitmapinfo->bmiColors[i].rgbReserved;  
  }  
  else  
  {  
          pDIBColors[i].rgbBlue=lpBitmapinfo->bmiColors[i].rgbBlue;  
  pDIBColors[i].rgbGreen=lpBitmapinfo->bmiColors[i].rgbGreen;  
  pDIBColors[i].rgbRed=lpBitmapinfo->bmiColors[i].rgbRed;  
  }  
        pGreyTable[i]=pDIBColors[i].rgbBlue*0.114+pDIBColors[i].rgbRed*0.299+pDIBColors[i].rgbGreen*0.587;  
  }  
  lpBit=lpBit+sizeof(BITMAPINFOHEADER)+PaletteSize(lpBit);  
  int   nRGB=(nWide*nCountBit+31)/32*4-(nWide*nCountBit)/8;  
  int   nGrey=(nWide*8+31)/32*4-nWide;  
  switch(nColorCount)  
  {  
  case   2:  
    for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  {  
  BYTE   n=1<<(7-j%8);  
  BYTE   Temp=*(BYTE*)lpBit;  
  Temp&=n;  
            *lpGrayBit++=pGreyTable[Temp>>(7-j%8)];  
    if((j+1)%8==0)lpBit++;  
  }  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
   
  break;  
  case     16:  
  //在我印像中还要分332A,和232之类的格式的.  
    for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  {  
   
  BYTE   Temp=*lpBit;  
  BYTE   n=j%2   ?0x0f:0xf0;  
  Temp&=n;  
  Temp=Temp>>(j%2   ?0:4);  
                  *lpGrayBit++=pGreyTable[Temp];  
  if((j+1)%2==0)lpBit++;  
  }  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
  break;  
  case   256:  
  //只处理基于调色板的DIB吗?  
  //好像有不是调色板的256色的图像的565或者是555A  
          for(i=0;i<nHeight;i++)  
  {  
  for(j=0;j<nWide;j++)  
  *lpGrayBit++=pGreyTable[(*lpBit++)];  
  lpGrayBit+=nGrey;  
  lpBit+=nRGB;  
  }  
   
  break;  
  }  
  ::GlobalUnlock((HGLOBAL)hDib);  
  ::GlobalFree((HGLOBAL)hDib);  
    hDib   =   hGreyDIB;  
  ::GlobalUnlock((HGLOBAL)hGreyDIB);  
  }  
  }  
原文地址http://topic.csdn.net/t/20021120/14/1191552.html
posted on 2007-07-11 11:05  Thunderdanky  阅读(1021)  评论(0)    收藏  举报