24位转成256色和16色,怎么转?

解决方案 »

  1.   

    24bit to 16bitred   =  (truecolor>>8)&0xf800;
    green =  (truecolor>>5)&0x7e0;
    blue  =  (truecolor>>3)&0x1f;
    hicolor=red|green|blue;
      

  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
      

  3.   

    有没有直接对象素的RGB进行转换的算法?
      

  4.   

    hehe ,我做过这样的东东,256色的8个bit 中(RGB332),
    一个语句就搞定了:
    return (P[tag].red/32*32+(P[tag].green/32)*4+P[tag].blue/64);
      

  5.   

    有没有直接对象素的RGB进行转换的算法?
    -------------------------------------------------
    肯定没有
    16色、256色都是调色版格式
    必须考虑色彩量化处理
    我以前用VB写的通过有序抖动保存各种格式的BMP(先进行相应抖动运算,再保存)的程序:
    http://zyl910vb.51.net/vb/map/ddsfDIB.htm
    右击连接,目标另存为
    注意把下载后的*.zip.jpg改名成*.zip
    这个程序是以前写的
    刚学计算机图形学
    不太懂
    效率较低
      

  6.   

    如果用了gammergr的方法觉得效果不好
    请联系我,不过是付费的!
      

  7.   

    CCh1_1Doc* pDoc = GetDocument();// 获取文档
    HDIB hDIB=pDoc->GetHDIB();
    m_UnDo=CopyHandle(hDIB);
    LPSTR lpDIB; // 指向DIB的指针
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());// 锁定DIB
    if (lpDIB==NULL)return;
    int NumColors;
    NumColors=((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
    if(NumColors!=24)
    {
    MessageBox("不是24位真彩位图,不能操作。");
    return;
    }
    BeginWaitCursor(); // 更改光标形状
    LPSTR   lpDIBBits;// 指向DIB图像开始处象素指针
    LPSTR   lpNewDIBBits;// 指向DIB灰度图图像开始处象素的指针
    unsigned char * ired;
    unsigned char * igreen;
    unsigned char * iblack;
    long i,j;// 循环变量
    long lWidth,lHeight;// 图像宽度,图像高度
    lWidth = ::DIBWidth(lpDIB); // 获取图像宽度
    lHeight = ::DIBHeight(lpDIB);// 获取图像高度
    lWidth =WIDTHBYTES(lWidth * 8);
    lpDIBBits=::FindDIBBits(lpDIB);// 找到DIB图像象素起始位置&lpDIB[sizeof(BITMAPINFOHEADER)];
    unsigned char * lpdest;
    lpdest=(unsigned char *)::malloc(lHeight*lWidth);
    int n=0;
    for(j = 0; j <3*lWidth*lHeight; n++,j=j+3)//读取图像数据并转化成灰度
    {
    ired= (unsigned char*)lpDIBBits +  j+2;
    igreen = (unsigned char*)lpDIBBits+j+1;
    iblack = (unsigned char*)lpDIBBits +j;
    lpdest[n] =(unsigned char)(0.299*(*ired)+0.587*(*igreen)+0.114*(*iblack));
    }
    LPBITMAPINFOHEADER lpBI;//位图信息头
    // 读取BITMAPINFO结构,初始化指针
    lpBI = (LPBITMAPINFOHEADER)lpDIB;//[sizeof(BITMAPFILEHEADER)];
    lpBI->biBitCount=8;
    //设置256色灰度调色板
    RGBQUAD *lpRGBquad;
    lpRGBquad=(RGBQUAD *)&lpDIB[sizeof(BITMAPINFOHEADER)];//位图信息头后面为调色板
    for (i = 0; i < 256; i++)
    {
    lpRGBquad[i].rgbRed =(unsigned char)i;// 读取红色分量
    lpRGBquad[i].rgbGreen =(unsigned char)i;// 读取绿色分量
    lpRGBquad[i].rgbBlue = (unsigned char)i;// 读取红色分量
    lpRGBquad[i].rgbReserved = 0;// 保留位
    }
    lpNewDIBBits= ::FindDIBBits(lpDIB);// 找到DIB图像象素起始位置
    unsigned char * lpSrc;
    for (i=0;i<lHeight*lWidth;i++)//写灰度图像数据
    {
    lpSrc=(unsigned char*)lpNewDIBBits+i;
    *lpSrc=lpdest[i];
    }
    ::free((void *)lpdest);
    pDoc->UpdateAllViews(NULL);//更新视图
    ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());// 解除锁定
    EndWaitCursor();// 恢复光标