小弟刚学编程,现在遇到这样一个问题:如何把BMP位图转换成灰度图?
哪位大哥最好能提供源码!谢谢!!!!!!!!!!!!

解决方案 »

  1.   

    BOOL ColorToGray(LPCSTR BmpFileName)
    {
    DWORD              SrcBufSize,DstBufSize,DstLineBytes;
        LPBITMAPINFOHEADER lpImgData;
    LPSTR              lpPtr;
    HLOCAL             hTempImgData;
    LPBITMAPINFOHEADER lpTempImgData;
    LPSTR              lpTempPtr;
    HDC                hDc;
    HFILE              hf;
    LONG               x,y;
    BITMAPFILEHEADER   DstBf;
    BITMAPINFOHEADER   DstBi;
        LOGPALETTE         *pPal;
        HPALETTE           hPrevPalette; 
    HLOCAL             hPal;
    DWORD    NewNumColors;
    WORD    NewBitCount;
    float              Y;
    DWORD              i;
    unsigned char      Red,Green,Blue,Gray; NewNumColors=NumColors;
    NewBitCount=bi.biBitCount;
    if(NumColors==0) //true color
    {
    NewNumColors=256;
    NewBitCount=8;
    } DstLineBytes=(DWORD)WIDTHBYTES(bi.biWidth*NewBitCount);
    DstBufSize=(DWORD)(sizeof(BITMAPINFOHEADER)+NewNumColors*sizeof(RGBQUAD)+(DWORD)DstLineBytes*bi.biHeight);
    memcpy((char *)&DstBf,(char *)&bf,sizeof(BITMAPFILEHEADER));
    memcpy((char *)&DstBi,(char *)&bi,sizeof(BITMAPINFOHEADER));
    DstBf.bfSize=DstBufSize+sizeof(BITMAPFILEHEADER);
    DstBf.bfOffBits=(DWORD)(NewNumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
    +sizeof(BITMAPINFOHEADER));
    DstBi.biClrUsed=0;
    DstBi.biBitCount=NewBitCount; SrcBufSize=bf.bfSize-sizeof(BITMAPFILEHEADER); if((hTempImgData=LocalAlloc(LHND,DstBufSize))==NULL)
        {
         MessageBox("Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }    lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
    lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData); //copy image data
    memcpy(lpTempImgData,lpImgData,DstBufSize);
    //overwrite bitmapinfoheader with the new one
    memcpy(lpTempImgData,(char *)&DstBi,sizeof(BITMAPINFOHEADER)); lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);
    lpTempPtr=(char *)lpTempImgData+sizeof(BITMAPINFOHEADER);    hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NewNumColors* sizeof(PALETTEENTRY));
        pPal =(LOGPALETTE *)LocalLock(hPal);
        pPal->palNumEntries =(WORD) NewNumColors;
    pPal->palVersion    = 0x300; if(NumColors==0) //true color
    for (i = 0; i < 256; i++) {
          pPal->palPalEntry[i].peRed=(BYTE)i;
    pPal->palPalEntry[i].peGreen=(BYTE)i;
    pPal->palPalEntry[i].peBlue=(BYTE)i;
    pPal->palPalEntry[i].peFlags=(BYTE)0;
    *(lpTempPtr++)=(unsigned char)i;
    *(lpTempPtr++)=(unsigned char)i;
    *(lpTempPtr++)=(unsigned char)i;
    *(lpTempPtr++)=0;
    }
    else 
    for (i = 0; i < NewNumColors; i++) {
    Blue=(unsigned char )(*lpPtr++);
    Green=(unsigned char )(*lpPtr++);
    Red=(unsigned char )(*lpPtr++);
    Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
    Gray=(BYTE)Y;
    lpPtr++;
          pPal->palPalEntry[i].peRed=Gray;
    pPal->palPalEntry[i].peGreen=Gray;
    pPal->palPalEntry[i].peBlue=Gray;
    pPal->palPalEntry[i].peFlags=0;
    *(lpTempPtr++)=(unsigned char)Gray;
    *(lpTempPtr++)=(unsigned char)Gray;
    *(lpTempPtr++)=(unsigned char)Gray;
    *(lpTempPtr++)=0;
    } if(hPalette!=NULL)                     
            DeleteObject(hPalette);

    hPalette=CreatePalette(pPal);
    LocalUnlock(hPal);
    LocalFree(hPal); hDc=::GetDC(m_hWnd);
    if(hPalette){
            hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
    RealizePalette(hDc);
    }

    if(NumColors==0)
    for(y=0;y<bi.biHeight;y++){
    lpPtr=(char *)lpImgData+(SrcBufSize-LineBytes-y*LineBytes);
    lpTempPtr=(char *)lpTempImgData+(DstBufSize-DstLineBytes-y*DstLineBytes);
    for(x=0;x<bi.biWidth;x++){
    Blue=(unsigned char )(*lpPtr++);
    Green=(unsigned char )(*lpPtr++);
    Red=(unsigned char )(*lpPtr++);
    Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
    Gray=(BYTE)Y;
    *(lpTempPtr++)=(unsigned char)Gray;
    }
    }    if(hBitmap!=NULL)
        DeleteObject(hBitmap);

    hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
    (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NewNumColors*sizeof(RGBQUAD),
        (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS); if(hPalette && hPrevPalette){
    SelectPalette(hDc,hPrevPalette,FALSE);
    RealizePalette(hDc);
    }    hf=_lcreat(BmpFileName,0);
    _lwrite(hf,(LPSTR)&DstBf,sizeof(BITMAPFILEHEADER)); 
    _lwrite(hf,(LPSTR)lpTempImgData,DstBufSize);
    _lclose(hf); ::ReleaseDC(m_hWnd,hDc);
    LocalUnlock(hTempImgData);
    LocalFree(hTempImgData);
    GlobalUnlock(hImgData);
    return TRUE;
    }
      

  2.   

    BOOL LoadBmpFile(LPCSTR BmpFileName)
    {
    HFILE              hf;
        LPBITMAPINFOHEADER lpImgData;
        LOGPALETTE         *pPal;
        LPRGBQUAD          lpRGB;
        HPALETTE           hPrevPalette; 
        HDC                hDc;
    HLOCAL             hPal;
    DWORD         ImgSize;
    DWORD              i;

        if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){
            MessageBox("Can not Load file","Error",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
    }
    _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
    _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
    ImgWidth=bi.biWidth;
    ImgHeight=bi.biHeight;
    LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
    ImgSize=(DWORD)LineBytes*bi.biHeight;
        if(bi.biClrUsed!=0)
    NumColors=(DWORD)bi.biClrUsed;
    else
            switch(bi.biBitCount){
    case 1:
    NumColors=2;
    break;
    case 4:
    NumColors=16;
    break;
    case 8:
    NumColors=256;
    break;
    case 24:
    NumColors=0;
    break;
    case 32:
    NumColors=0;
    break;
    default:
    MessageBox("Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE; 
    NumColors = 0;
    break;
    }

    if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
    +sizeof(BITMAPINFOHEADER)))
    {
    MessageBox("Invalid color numbers!","Error Message" ,MB_OK|
    MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE; 
    }

    bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
    if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
    NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
    {
    MessageBox("Error alloc memory!","ErrorMessage",MB_OK|
    MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE;
    }

    lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
        _llseek(hf,sizeof(BITMAPFILEHEADER),FILE_BEGIN);
    _hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
    +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
    _lclose(hf);
        if(NumColors!=0)
    {                    
    hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
    pPal =(LOGPALETTE *)LocalLock(hPal);
    pPal->palNumEntries =(WORD) NumColors;
    pPal->palVersion    = 0x300;
    lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
    for (i = 0; i < NumColors; i++) {
    pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
    pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
    pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
    pPal->palPalEntry[i].peFlags=(BYTE)0;
    lpRGB++;
    }
    hPalette=CreatePalette(pPal);
    LocalUnlock(hPal);
    LocalFree(hPal);
    }
    hDc=::GetDC(m_hWnd);
    if(hPalette){
            hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
    RealizePalette(hDc);
    }
    hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
    (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
    (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
    if(hPalette && hPrevPalette){
    SelectPalette(hDc,hPrevPalette,FALSE);
    RealizePalette(hDc);
    }

    ::ReleaseDC(m_hWnd,hDc);
    GlobalUnlock(hImgData);
    GetDocument()->SetTitle( BmpFileName );
    return TRUE; 
    }
      

  3.   

    //全局變量
    #define WIDTHBYTES(i)    ((i+31)/32*4)
    BITMAPFILEHEADER   bf;
    BITMAPINFOHEADER   bi;
    HPALETTE           hPalette=NULL;
    HBITMAP            hBitmap=NULL;
    HGLOBAL            hImgData=NULL;
    DWORD              NumColors;
    DWORD              LineBytes;
    HINSTANCE          ghInst;
    DWORD              ImgWidth=0 , ImgHeight=0;
    int GrayTable[256];
    int MaxGrayNum;
    int MinGrayNum;
    int FirstPoint=0, SecondPoint=255;
    float StretchRatio=2.0f;
    int EquaScale;
      

  4.   

    //Usage:
           
    if(LoadBmpFile("E:\\Test.bmp"))
    {
        ColorToGray("E:\\Gray.bmp");
    }