说实话,我也不停地努力了,试图自己编出这个程序。但是我本身是学测控的,VC的基础实在薄弱,而且我后期还得做很多其它东西,所以我只好来直接求源码了。自己网上搜索好久也没找到,有知道的同仁请伸出您的援助之手吧^_^
QQ94174927,mail:[email protected]
不胜感激~

解决方案 »

  1.   

    我自己写的函数,已经验证通过了,首先你要添加一个dib的类,网上有很多,或者你可以直接在msdn搜索diblook,使用它提供的dibapi.h和dibapi.cpp,然后将函数加进去就可以使用了。
    HDIB CDibImage::RGB2Gray(HDIB hRGBDib)
    {
    BYTE* lpRGBDIB = (BYTE*)GlobalLock((HGLOBAL)hRGBDib);
    BITMAPINFO* pRGBbmi = (BITMAPINFO*)lpRGBDIB;
    if(pRGBbmi->bmiHeader.biBitCount != 24)
    {
    AfxMessageBox("This is not a 24bit bmp");
    return 0;
    }
    int width = pRGBbmi->bmiHeader.biWidth;
    int height = pRGBbmi->bmiHeader.biHeight;
    BYTE* lpRGBData = lpRGBDIB+sizeof(BITMAPINFOHEADER); HDIB hGrayDib = NULL;
    hGrayDib = (HDIB)GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height);
    if(!hGrayDib)
    {
    AfxMessageBox("GlobalAlloc fail");
    return 0;
    }
    BYTE* lpGrayDIB = (BYTE*)GlobalLock((HGLOBAL)hGrayDib);
    ZeroMemory(lpGrayDIB, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height);
    BITMAPINFO* pGraybmi = (BITMAPINFO*)lpGrayDIB;
    pGraybmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pGraybmi->bmiHeader.biWidth = width;
    pGraybmi->bmiHeader.biHeight = height;
    pGraybmi->bmiHeader.biPlanes = 1;
    pGraybmi->bmiHeader.biBitCount = 8;
    pGraybmi->bmiHeader.biCompression = BI_RGB;
    for(int i = 0; i < 256; i++)
    {
    pGraybmi->bmiColors[i].rgbBlue = (BYTE)i;
    pGraybmi->bmiColors[i].rgbGreen = (BYTE)i;
    pGraybmi->bmiColors[i].rgbRed = (BYTE)i;
    pGraybmi->bmiColors[i].rgbReserved = 0;
    }
    BYTE* lpGrayData = (BYTE*)lpGrayDIB+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
    double value;
    for(i = 0; i < width*height; i++)
    {
    value = lpRGBData[3*i]*0.114+lpRGBData[3*i+1]*0.587+lpRGBData[3*i+2]*0.299;
    lpGrayData[i] = (unsigned char)value;
    } return hGrayDib;}
      

  2.   

    sorry,看错了,流行色算法好像比较麻烦把,先要对颜色进行统计,然后取使用频率高的256种颜色构造调色板,没做过
      

  3.   

    搞定了,在上面那个函数基础上改的,有的变量命名可能不太确切,请见谅
    HDIB CDibImage::RGBMinus(HDIB hRGBDib)
    {
    BYTE* lpRGBDIB = (BYTE*)GlobalLock((HGLOBAL)hRGBDib);
    BITMAPINFO* pRGBbmi = (BITMAPINFO*)lpRGBDIB;
    if(pRGBbmi->bmiHeader.biBitCount != 24)
    {
    AfxMessageBox("This is not a 24bit bmp");
    return 0;
    }
    int width = pRGBbmi->bmiHeader.biWidth;
    int height = pRGBbmi->bmiHeader.biHeight;
    BYTE* lpRGBData = lpRGBDIB+sizeof(BITMAPINFOHEADER); HDIB hGrayDib = NULL;
    hGrayDib = (HDIB)GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height);
    if(!hGrayDib)
    {
    AfxMessageBox("GlobalAlloc fail");
    return 0;
    }
    BYTE* lpGrayDIB = (BYTE*)GlobalLock((HGLOBAL)hGrayDib);
    ZeroMemory(lpGrayDIB, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+width*height);
    BITMAPINFO* pGraybmi = (BITMAPINFO*)lpGrayDIB;
    pGraybmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pGraybmi->bmiHeader.biWidth = width;
    pGraybmi->bmiHeader.biHeight = height;
    pGraybmi->bmiHeader.biPlanes = 1;
    pGraybmi->bmiHeader.biBitCount = 8;
    pGraybmi->bmiHeader.biCompression = BI_RGB; DWORD color[4096];
    WORD index[4096];
    memset(&color, 0, sizeof(color));
    memset(&index, 0, sizeof(index));
    int red, green, blue;
    int clrind;
    for(int i = 0; i < width*height; i++)
    {
    blue = (int)(lpRGBData[3*i] & 0xf0);
    green = (int)(lpRGBData[3*i+1] & 0xf0);
    red = (int)(lpRGBData[3*i+2] & 0xf0);
    clrind = (blue<<4) + green + (red>>4);
    color[clrind]++;
    }
    int clrcnt = 0;
    for(i = 0; i < 4096; i++)
    {
    if(color[i] > 0)
    {
    color[clrcnt] = color[i];
    index[clrcnt] = i;
    clrcnt++;
    }
    }
    int j, temp;
    for(i = 0; i < clrcnt-1; i++)
    for(j = i+1; j < clrcnt; j++)
    {
    if(color[i] < color[j])
    {
    temp = (int)color[i];
    color[i] = color[j];
    color[j] = (DWORD)temp;
    temp = (int)index[i];
    index[i] = index[j];
    index[j] = (WORD)temp;
    }
    }
    for(i = 0; i < 256; i++)
    {
    pGraybmi->bmiColors[i].rgbBlue = (BYTE)((index[i]&0xF00)>>4);
    pGraybmi->bmiColors[i].rgbGreen = (BYTE)((index[i]&0x0F0));
    pGraybmi->bmiColors[i].rgbRed = (BYTE)((index[i]&0x00F)<<4);
    pGraybmi->bmiColors[i].rgbReserved = 0;
    color[i] = (DWORD)i;
    }
    int deviation, dmin;
    if(clrcnt > 256)
    {
    for(i = 256; i < clrcnt; i++)
    {
    dmin = 2000000000;
    blue = (int)((index[i]&0xF00)>>4);
    green = (int)((index[i]&0x0F0));
    red = (int)((index[i]&0x00F)<<4);
    clrind = 0;
    for(j = 0; j < 256; j++)
    {
    deviation = (pGraybmi->bmiColors[j].rgbBlue-blue)*(pGraybmi->bmiColors[j].rgbBlue-blue)
    + (pGraybmi->bmiColors[j].rgbGreen-green)*(pGraybmi->bmiColors[j].rgbGreen-green)
    + (pGraybmi->bmiColors[j].rgbRed-red)*(pGraybmi->bmiColors[j].rgbRed-red);
    if(deviation < dmin)
    {
    dmin = deviation;
    clrind = j;
    }
    }
    color[i] = (DWORD)clrind;
    }
    }
    BYTE* lpGrayData = (BYTE*)lpGrayDIB+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);

    for(i = 0; i < width*height; i++)
    {
    blue = (int)(lpRGBData[3*i] & 0xf0);
    green = (int)(lpRGBData[3*i+1] & 0xf0);
    red = (int)(lpRGBData[3*i+2] & 0xf0);
    clrind = (blue<<4) + green + (red>>4);
    for(j = 0; j < clrcnt; j++)
    {
    if(index[j] == clrind)
    {
    lpGrayData[i] = (unsigned char)color[j];
    break;
    }
    }
    } return hGrayDib;}
      

  4.   

    我自己建了Dib类了 并且把这个函数加载到DIb类
    我在ONDraw函数里调用这个类:
    CDib m_Dib;
    m_Dib.RGB2Gray(?);
    我应该把什么当成这里的“?”呢
      

  5.   

    你应该先读入你的真彩色图像,如果你是使用的DIBLOOK sample [MFC]中的dibapi的话就是HDIB ReadDIBFile(CFile& file),这个函数返回的就是你的真彩色图像的句柄,比如:
    HDIB hRGBDIB = ReadDIBFile(CFile& file);
    HDIB hNewDIB = RGBMinus(hRGBDib);
    BYTE* lpDIB = (BYTE*)GlobalLock((HGLOBAL)hNewDIB);
    BITMAPINFOHEADER* pbmi = (BITMAPINFOHEADER*)lpDIB;
    int w =  (int)pbmi->biWidth;
    int h = (int)pbmi->biHeight;
    BYTE* lpDIBBits = (BYTE*)lpDIB+sizeof(BITMAPINFOHEADER);
    StretchDIBits(pDC->GetSafeHdc(),0,0,w,h,0,0,w,h,lpDIBBits,(BITMAPINFO*)pbmi,DIB_RGB_COLORS,SRCCOPY);
    GlobalUnlock((HGLOBAL)hNewDIB);
      

  6.   

    不好意思,上面有点问题,把BYTE* lpDIBBits = (BYTE*)lpDIB+sizeof(BITMAPINFOHEADER);改为BYTE* lpDIBBits = (BYTE*)lpDIB+sizeof(BITMAPINFOHEADER)+256×sizeof(RGBQUAD);
      

  7.   

    恩 yesir1006我在编译的时候老是出错 
    我用的是自己编的Dib
    你能加我QQ么 ?
    94174927
      

  8.   

    我把我用的DIB类给贴出来你给我整理成一个程序行么?
    // DIB.h#ifndef __DIB_H__
    #define __DIB_H__class CDib
    {public:
    LPBYTE m_lpImage;
    CDib();
    ~CDib(); BOOL Load( const char * );
    BOOL Save( const char * );
    BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 ); DWORD m_dwDibSize;
    PBITMAPINFO m_pBMI; CSize m_ImageSize;
    DWORD m_dwSizeImage;    unsigned char *pD;
    unsigned char *m_pDibBits;
    unsigned char *m_pDibBits0;

    private:
    };#endif下面是源文件:
    // DIB.cpp#include "stdafx.h"
    #include "DIB.h"CDib::CDib()
    { // Set the Dib pointer to
    // NULL so we know if it's
    // been loaded.
    pD = NULL;
    m_pBMI=NULL;
    m_lpImage=NULL;
    }CDib::~CDib()
    { // If a Dib has been loaded,
    // delete the memory.
    if( pD != NULL )
    delete [] pD;
    if(m_pBMI!=NULL)
    {
           delete [] m_pBMI;
    }
      if(m_lpImage!=NULL)
    {
           delete [] m_lpImage;
    }
    }BOOL CDib::Load( const char *pszFilename )
    {
    if(pD!=NULL)
    {
    delete[] pD;
    pD=NULL;
    }
    if(m_pBMI!=NULL)
    {
    delete[] m_pBMI;
    m_pBMI=NULL;
    }
    if(m_lpImage!=NULL)
    {
    delete[] m_lpImage;
    m_lpImage=NULL;
    }
    CFile pFile;
        pFile.Open( pszFilename, CFile::modeRead ) ; DWORD dwSize;
    dwSize =pFile.GetLength() - sizeof( BITMAPFILEHEADER );
    BITMAPFILEHEADER bmfh;    pFile.Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));

    pD = new unsigned char [dwSize];
    pFile.Read( pD, dwSize );
    BITMAPINFOHEADER *m_pBIH = (BITMAPINFOHEADER *) pD;
    int m_nPaletteEntries = 1 <<m_pBIH->biBitCount; if( m_pBIH->biBitCount > 8 )
    m_nPaletteEntries = 0;
    else if( m_pBIH->biClrUsed != 0 )
    m_nPaletteEntries = m_pBIH->biClrUsed; m_pBMI = (PBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) + m_nPaletteEntries*sizeof(RGBQUAD)];// pFile.Read(m_pBMI, (sizeof(BITMAPINFOHEADER) + m_nPaletteEntries*sizeof(RGBQUAD))) memcpy(m_pBMI, pD, sizeof(BITMAPINFOHEADER) + m_nPaletteEntries*sizeof(RGBQUAD)); m_ImageSize.cx = m_pBMI->bmiHeader.biWidth;
    m_ImageSize.cy = m_pBMI->bmiHeader.biHeight;
    m_dwSizeImage = m_ImageSize.cx * m_ImageSize.cy;
    m_pDibBits =&pD[sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD)];
    // m_lpImage = (LPBYTE) new BYTE[m_dwSizeImage];
    // pFile.Read(m_lpImage, m_dwSizeImage);
          //  m_pDibBits0=m_pDibBits+sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD);

    pFile.Close(); 
    //   m_pBMI->bmiColors[20].rgbBlue = (BYTE)255;  
    //   m_pBMI->bmiColors[20].rgbGreen = (BYTE)0;
    //   m_pBMI->bmiColors[20].rgbRed = (BYTE)0;
    //   m_pBMI->bmiColors[20].rgbReserved = 0; return true;
    }BOOL CDib::Save( const char *pszFilename )
    { CFile pFile; pFile.Open( pszFilename,CFile::modeCreate | CFile::modeWrite );

        BITMAPFILEHEADER bmfh; bmfh.bfType = 0x4d42;   // 计算信息头的大小尺寸
    int nSizebmpi = sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD); // 设置文件头信息
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizebmpi + m_dwSizeImage;
    bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + nSizebmpi;

    pFile.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
    pFile.Write((LPVOID) m_pBMI,  nSizebmpi);
    pFile.Write(m_pDibBits, m_dwSizeImage); pFile.Close();
        
    return true;
    }BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight )
    {
    pDC->SetStretchBltMode(COLORONCOLOR);
    StretchDIBits( pDC->m_hDC, nX, nY,
    nWidth, nHeight,
    0, 0,
    m_ImageSize.cx, m_ImageSize.cy,
    m_pDibBits, m_pBMI,
    DIB_RGB_COLORS, SRCCOPY );

    return( TRUE );}
      

  9.   

    自己顶顶 希望yesir1006能尽早进来~~