256色转灰度+24位真彩色转灰度

来源:互联网 发布:生产数据统计岗位职责 编辑:程序博客网 时间:2024/06/05 10:21

来源:http://blog.csdn.net/sunny3106/archive/2007/08/27/1761106.aspx

/****************************************************************
*
* 函数名称:     Convert256toGray(LPSTR lpDIB,LPSTR lpDIBBits,
   long   lWidth,long   lHeight)
* 参数:   LPSTR lpDIB      指向dib的指针
                 LPSTR lpDIBBits   指向dib数据的指针
                 long   lWidth     图像宽度
                 long   lHeight    图像高度
* 返回值:       bool
* 功能:         将256色位图转化为灰度图
*
***************************************************************/

bool Convert256toGray(LPSTR lpDIB,LPSTR lpDIBBits,
   long   lWidth,long   lHeight)
{
 BYTE * lpSrc;  // 指向DIB象素的指针
 LONG lLineBytes;     // 图像每行的字节数
 LPBITMAPINFO lpbmi;   // 指向BITMAPINFO结构的指针(Win3.0)
 LPBITMAPCOREINFO lpbmc;    // 指向BITMAPCOREINFO结构的指针
 lpbmi = (LPBITMAPINFO)lpDIB; // 获取指向BITMAPINFO结构的指针(Win3.0)
 lpbmc = (LPBITMAPCOREINFO)lpDIB; // 获取指向BITMAPCOREINFO结构的指针
 
 BYTE bMap[256];   // 灰度映射表
 
 // 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
 int i,j;
 for (i = 0; i < 256; i ++)
 {
  // 计算该颜色对应的灰度值

/*
  bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +

                                  0.587 * lpbmi->bmiColors[i].rgbGreen +

                                 0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);  

*/

  bMap[i] = (BYTE)((306 * lpbmi->bmiColors[i].rgbRed +

                                  601 * lpbmi->bmiColors[i].rgbGreen +

                                 117 * lpbmi->bmiColors[i].rgbBlue + 512) >> 10 );   //修改后的优化算法


  // 更新DIB调色板红色分量
  lpbmi->bmiColors[i].rgbRed = i;
 
  // 更新DIB调色板绿色分量
  lpbmi->bmiColors[i].rgbGreen = i;
 
  // 更新DIB调色板蓝色分量
  lpbmi->bmiColors[i].rgbBlue = i;
  
  // 更新DIB调色板保留位
  lpbmi->bmiColors[i].rgbReserved = 0;

 }

 // 计算图像每行的字节数
 lLineBytes = WIDTHBYTES(lWidth * 8);

 // 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)

 //逐行扫描
 for(i = 0; i < lHeight; i++)
 {

  //逐列扫描
  for(j = 0; j < lWidth; j++)
  {
   // 指向DIB第i行,第j个象素的指针
   lpSrc = (unsigned char*)lpDIBBits
    + lLineBytes * (lHeight - 1 - i) + j;
  
   // 变换
   *lpSrc = bMap[*lpSrc];
  }
 }
    return true;
}

/*************************************************************************
 * 函数名称:Gray24Bits(LPSTR lpDIB)
 * 函数类型:HGLOBAL
 * 参数:    LPSTR lpDIB           指向dib的指针
 * 函数功能:灰度化24位真彩图像
 *************************************************************************/
HGLOBAL Gray24Bits(LPSTR lpDIB)
{
 
 LPBITMAPINFOHEADER lpDIBHdr;             // 指向BITMAPINFOHEADER的指针
 lpDIBHdr = (LPBITMAPINFOHEADER)lpDIB;
 
 LPSTR lpGray;

 // 计算位图图的信息头、调色板和图形数据的大小, 并给灰度图分配内存
 int dwInfo = lpDIBHdr->biSize;
 int dwData = lpDIBHdr->biSizeImage;
 int dwGrayData = dwData/3;
 int dwGrayPal = 256 * sizeof(RGBQUAD);
    dwData=(lpDIBHdr->biHeight) * (lpDIBHdr->biWidth);
 int sizeTotal=dwInfo+dwGrayPal+dwData;         //灰度图,颜色表长度为255
 HGLOBAL hGray=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeTotal);
 if (hGray==0)
 {
  return false;  //内存分配失败则返回false
 }
 lpGray = (LPSTR) ::GlobalLock(hGray);

 // 创建灰度图的颜色表  计算每个像素点的灰度值,即求平均即可
    RGBQUAD* lpGrayRgbQuag=(RGBQUAD*)(lpGray+lpDIBHdr->biSize);

 char * lpBits = lpDIB + lpDIBHdr->biSize ;
 int  rowLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
 int  rowLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
 BYTE * lpGrayBits = (BYTE*)(lpGrayRgbQuag)+dwGrayPal;
 
 int aver=0;
 int i,j,k;

 if(24==lpDIBHdr->biBitCount)
 { 
   for(i=0;i<256;i++)
   {
            lpGrayRgbQuag->rgbBlue=i;
            lpGrayRgbQuag->rgbGreen=i;
            lpGrayRgbQuag->rgbRed=i;
            lpGrayRgbQuag->rgbReserved=0;
   lpGrayRgbQuag++;
   }

 
   
        for (i=0;i<lpDIBHdr->biHeight;i++)
  {
            for (j=0; j<lpDIBHdr->biWidth; j++)
   {
                 k=i*rowLenSr+3*j;

/*
                 lpGrayBits[i*rowLenDes+j]=(BYTE)(0.114*lpBits[k]
                                                                                  + 0.587*lpBits[k+1]
                                                                                  + 0.299*lpBits[k+2] + 0.5);

*/

                 lpGrayBits[i*rowLenDes+j]=(BYTE) (( 117 * lpBits[k]
                                                                                  +  601 * lpBits[k+1]
                                                                                  +  306 * lpBits[k+2] + 512 ) >> 10 );  //修改后的优化算法
   }
         //修正需要补零的像素行
            for (j=lpDIBHdr->biWidth;j<rowLenDes;j++)
   {
                  lpGrayBits[i*rowLenDes+j]=0;
   }

  }
 }

 // 创建灰度图的信息头
 LPBITMAPINFOHEADER lpGrayHdr=(LPBITMAPINFOHEADER)lpGray;
 memcpy(lpGrayHdr, lpDIBHdr, dwInfo);

 lpGrayHdr->biSizeImage=sizeTotal;
 lpGrayHdr->biBitCount=8;
    lpGrayHdr->biClrUsed=256;

    ::GlobalUnlock( hGray );
    return (HGLOBAL) hGray;
}

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sunny3106/archive/2007/08/27/1761106.aspx

原创粉丝点击