我有一个真彩色位图文件(A.BMP),现在想把它转换成256色的位图文件(B.BMP),请问如何实现?

解决方案 »

  1.   

    1、mspaint打开,另存为256色bmp.
    2、HBITMAP LoadBitmap(
      HINSTANCE hInstance,  // handle to application instance
      LPCTSTR lpBitmapName  // address of bitmap resource name
    );BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
     HBITMAP  hBmp, // DDB for convert
     int nBitCount, int nCompression) // format wanted
    {
    typedef struct
    {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD        bmiColors[256+3];
    } DIBINFO; BITMAP  ddbinfo;
    DIBINFO dibinfo; // retrieve DDB information
    if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 )
    return NULL; // fill out BITMAPINFOHEADER based on size and required format
    memset(&dibinfo, 0, sizeof(dibinfo)); dibinfo.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    dibinfo.bmiHeader.biWidth       = ddbinfo.bmWidth;
    dibinfo.bmiHeader.biHeight      = ddbinfo.bmHeight;
    dibinfo.bmiHeader.biPlanes      = 1;
    dibinfo.bmiHeader.biBitCount    = nBitCount;
    dibinfo.bmiHeader.biCompression = nCompression; HDC     hDC = GetDC(NULL); // screen DC
    HGDIOBJ hpalOld;

    if ( hPal )
    hpalOld = SelectPalette(hDC, hPal, FALSE);
    else
    hpalOld = NULL; // query GDI for image size
    GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS); int nInfoSize  = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);
    int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader); BYTE * pDIB = new BYTE[nTotalSize]; if ( pDIB )
    {
    memcpy(pDIB, & dibinfo, nInfoSize);

    if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )
    {
    delete [] pDIB;
    pDIB = NULL;
    }
    } if ( hpalOld )
    SelectObject(hDC, hpalOld); ReleaseDC(NULL, hDC); return (BITMAPINFO *) pDIB;
    }BOOL SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits)
    {
    if(pFileName==NULL){
    return FALSE;
    } HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ, 
    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if(handle == INVALID_HANDLE_VALUE){
    return FALSE;
    } BITMAPFILEHEADER bmFH; int nHeadSize = sizeof(BITMAPINFOHEADER) + 
    sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader); bmFH.bfType      = 0x4D42;
    bmFH.bfSize      = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader);
    bmFH.bfReserved1 = 0;
    bmFH.bfReserved2 = 0;
    bmFH.bfOffBits   = nHeadSize + sizeof(BITMAPFILEHEADER); DWORD dwRead = 0;
    WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL); if(pBits==NULL) // packed DIB
    pBits = (BYTE *) pBMI + nHeadSize;

    WriteFile(handle, pBMI,  nHeadSize,    & dwRead, NULL);
    WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL); CloseHandle(handle); return TRUE;
    }给下面函数nBitCount 传递8表示保存为256色位图
    BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
     HBITMAP  hBmp, // DDB for convert
     int nBitCount, int nCompression) // format wanted
      

  2.   

    谢谢oldworm(oldworm),我试过OK后,马上给分!
      

  3.   

    oldworm(oldworm),编译后有以下三个错误:error C2065: 'GetDIBColorCount' : undeclared identifier
    error C2065: 'GetDIBPixelSize' : undeclared identifier
    error C2660: 'ReleaseDC' : function does not take 2 parameters何解?
      

  4.   

    romanticist(让我拥抱你入梦),为什么在MSDN里找不到?是用户自己定义的吗?
      

  5.   

    int GetDIBPixelSize(const BITMAPINFOHEADER & bmih)
    {
    if ( bmih.biSizeImage )
    return bmih.biSizeImage;
    else
    return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
    }int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
    {
    if ( bmih.biBitCount <= 8 )
    if ( bmih.biClrUsed )
    return bmih.biClrUsed;
    else
    return 1 << bmih.biBitCount;
    else if ( bmih.biCompression==BI_BITFIELDS )
    return 3 + bmih.biClrUsed;
    else
    return bmih.biClrUsed;
    }Release修改为:
    ::ReleaseDC你是不是将代码拆开了拿到你的程序中调用的?
      

  6.   

    oldworm(oldworm):是啊!我再试试看,谢谢!!
      

  7.   

    http://www.enwww.net/mysoftware/64kbmp2gray.zip
    借花
      

  8.   

    谢谢rujor(rujor),但是运行不是很理想。
      

  9.   

    oldworm(oldworm),我还没有试出来,或者你告诉我如何调用你的那些函数吧。
    我现在有一幅图(C:\A.bmp),它是真彩格式,怎么变成256色的图(C:\B.bmp)?
      

  10.   

    楼主要的是灰度图吗?是的话,rujor(rujor)的可以,不过他的是16位的,还有处理24位的,实际上只是把真彩图的每个象素的R,G,B三色用(r*0.29900 + g*0.58700 + b*0.11400)转一下换成在256色表中的索引。
    如果是降色的话,算法比较繁了。
      

  11.   

    paul2002():不是灰度图图,你有24位转为8位的例程吗?oldworm(oldworm):还是不行啊!?
      

  12.   

    谢谢各位!我已经在以下网址找到正确的方法,不敢独享:http://msdn.microsoft.com/code/default.asp?url=/msdn-files/026/000/209/Source%20Files/AOTBLOBDlg_cpp.asp
    当然,分数还是照给不误!谢谢捧场!!!