32位彩色图像转换成256级灰度图的算法

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);  
  }  
  }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值