我前几天刚写了个这个程序,我的做法是生成一个新的DIB,新DIB是256色,每色的R,G,B都是相同的,并且和它们的索引值相同,进行灰度变换时直接把新DIB的每个点数据(8位索引)设置成灰度值。不知道我说的够清楚不?

解决方案 »

  1.   

    补充下上面的“新DIB是256色,每色的R,G,B都是相同的,并且和它们的索引值相同”指的是调色版;
    另DIB本身不支持灰度图,还有一种比较简单的算法就是把调色版的颜色进行灰度变换,但是新DIB和源DIB同大小
      

  2.   

    但图像大小并没变成彩色图的1/3
    那是因为你的变更后的图像实际上还是24位的。只是他们的R/G/B分量相同而已
      

  3.   

    先创建8位的DIB,设置其调色板(这一定要做),然后就是根据彩色图像像这个8位DIB写数据了啊!
      

  4.   

    楼住可以看下我的代码 中间有一些函数是自己写的,不过不影响算法,主要的一个是上面部分的生成调色版,一个是下面的循环做灰度变换
    CDib* CDib::GetGrayDib(double dRedWeight,double dGreenWeight,double dBlueWeight)
    {
    HDIB hNewDib=CreateDIB(m_nWidth,m_nHeight,8);//创建新的DIB
    LPBITMAPINFO lpNewDib=(LPBITMAPINFO)GlobalLock(hNewDib); //设置灰度图的Palette for(int i=0;i<256;i++)
    {
    lpNewDib->bmiColors[i].rgbBlue=
    lpNewDib->bmiColors[i].rgbGreen=
    lpNewDib->bmiColors[i].rgbRed=BYTE(i);
    } CDib* pNewDib=new CDib;
    if(NULL==pNewDib)return NULL;

    pNewDib->Create((LPBYTE)lpNewDib);
    GlobalUnlock(hNewDib);
    GlobalFree(hNewDib);
    pNewDib->UpdateInternal();
    COLORREF cColor;
    BYTE*  lPixel;
    SetDibPtrBegin(this);
    SetDibPtrBegin(pNewDib);
    for(UINT nHeight=0;nHeight<m_nHeight;nHeight++)
    {
    for(UINT nWidth=0;nWidth<m_nWidth;nWidth++)
    {
    cColor=GetPixel(nWidth,nHeight);
    lPixel=(BYTE*)(pNewDib->m_lpData+pNewDib->GetPixelOffset(nWidth,nHeight));
    (*lPixel)=(BYTE)(GetRValue(cColor)*dRedWeight+
     GetGValue(cColor)*dGreenWeight+
     GetBValue(cColor)*dBlueWeight);
    }
    }
    SetDibPtrEnd(pNewDib);
    SetDibPtrEnd(this);
    pNewDib->UpdateInternal();
    return pNewDib;
    }