现在有一调色板有256项,每项为r,g,b三值,共占768,现24位RGB色使用该调色板,查找颜色最相近的调色板项代替原来颜色
编程实现 int fastFind(char *pal,r,g,b)
屏幕显示800*600*24

解决方案 »

  1.   

    有个权值,
    temp=(int)((float)(pData24[i*nLineBytes+3*j]*BLUE_WEIGHT+
    (float)pData24[i*nLineBytes+3*j+1]*GREEN_WEIGHT+
    (float)pData24[i*nLineBytes+3*j+2]*RED_WEIGHT));
    其中,
    #ifndef RED_WEIGHT
    #define RED_WEIGHT 0.299
    #endif
    #ifndef GREEN_WEIGHT
    #define GREEN_WEIGHT 0.587
    #endif
    #ifndef BLUE_WEIGHT
    #define BLUE_WEIGHT 0.114
    #endif
      

  2.   

    void OnConvertRGBto256()
    {
    LPBITMAPINFO lpBi;
    LPBITMAPINFO lpBi24;
    HGLOBAL hDIB;
    DWORD dwSize;
    int nSizeCT;
    int i, j;
    int n;
    LPSTR lpRowSrc;
    LPSTR lpRowTgt;
    POSITION pos;
    CGDIView *ptrView;
    CPtrArray arRgbQuad;
    LPRGBQUAD lpRgbQuad;
    RGBQUAD rgbQuad;
    BOOL bHit;
    BOOL bStandardPal;
    BYTE red, green, blue;
    AfxGetApp()->DoWaitCursor(TRUE);
    lpBi24=(LPBITMAPINFO)::GlobalLock(m_hDIB);
    ASSERT(lpBi24);
    for(j=0; j<lpBi24->bmiHeader.biHeight; j++)
    {
    lpRowSrc=
    ((LPSTR)lpBi24+
    sizeof(BITMAPINFOHEADER)+
    WIDTHBYTES(lpBi24->bmiHeader.biBitCount*lpBi24->bmiHeader.biWidth)*j
    );
    for(i=0; i<lpBi24->bmiHeader.biWidth; i++)
    {
    rgbQuad.rgbBlue=*lpRowSrc;
    rgbQuad.rgbGreen=*(lpRowSrc+1);
    rgbQuad.rgbRed=*(lpRowSrc+2);
    rgbQuad.rgbReserved=0;
    bHit=FALSE;
    for(n=0; n<arRgbQuad.GetSize(); n++)
    {
    if
    (
    !memcmp
    (
    (LPSTR)&rgbQuad,
    (LPSTR)arRgbQuad[n],
    sizeof(RGBQUAD)
    )
    )
    {
    bHit=TRUE;
    break;
    }
    }
    if(bHit == FALSE)
    {
    lpRgbQuad=new RGBQUAD;
    *lpRgbQuad=rgbQuad;
    arRgbQuad.Add(lpRgbQuad);
    }
    lpRowSrc+=3;
    }
    }
    if(arRgbQuad.GetSize() > 256)
    {
    while(arRgbQuad.GetSize())
    {
    delete (LPRGBQUAD)arRgbQuad.GetAt(0);
    arRgbQuad.RemoveAt(0);
    }
    red=green=blue=0;
    for(i=0; i<256; i++)
    {
    lpRgbQuad=new RGBQUAD;
    lpRgbQuad->rgbBlue=blue;
    lpRgbQuad->rgbGreen=green;
    lpRgbQuad->rgbRed=red;
    lpRgbQuad->rgbReserved=0;
    if(!(red+=32))if(!(green+=32))blue+=64;
    arRgbQuad.Add(lpRgbQuad);
    }
    bStandardPal=TRUE;
    }
    else bStandardPal=FALSE;
    nSizeCT=256;
    dwSize=
    (
    sizeof(BITMAPINFOHEADER)+
    nSizeCT*sizeof(RGBQUAD)+
    WIDTHBYTES(8*lpBi24->bmiHeader.biWidth)*lpBi24->bmiHeader.biHeight
    );
    hDIB=::GlobalAlloc(GHND, dwSize);
    ASSERT(hDIB);
    lpBi=(LPBITMAPINFO)::GlobalLock(hDIB);
    ASSERT(lpBi);
    *lpBi=*lpBi24;
    lpBi->bmiHeader.biBitCount=8;
    lpBi->bmiHeader.biSizeImage=WIDTHBYTES
    (
    8*lpBi->bmiHeader.biWidth
    )*lpBi->bmiHeader.biHeight;
    lpBi->bmiHeader.biClrUsed=0;
    for(n=0; n<arRgbQuad.GetSize(); n++)
    {
    lpBi->bmiColors[n]=*(LPRGBQUAD)arRgbQuad[n];
    }
    for(j=0; j<lpBi->bmiHeader.biHeight; j++)
    {
    lpRowTgt=
    (
    (LPSTR)lpBi+
    sizeof(BITMAPINFOHEADER)+
    nSizeCT*sizeof(RGBQUAD)+
    WIDTHBYTES(lpBi->bmiHeader.biBitCount*lpBi->bmiHeader.biWidth)*j
    );
    lpRowSrc=
    (
    (LPSTR)lpBi24+
    sizeof(BITMAPINFOHEADER)+
    WIDTHBYTES(lpBi24->bmiHeader.biBitCount*lpBi24->bmiHeader.biWidth)*j
    );
    for(i=0; i<lpBi->bmiHeader.biWidth; i++)
    {
    rgbQuad.rgbBlue=*lpRowSrc;
    rgbQuad.rgbGreen=*(lpRowSrc+1);
    rgbQuad.rgbRed=*(lpRowSrc+2);
    rgbQuad.rgbReserved=0;
    if(bStandardPal == TRUE)
    {
    if(rgbQuad.rgbBlue <= 0xdf)rgbQuad.rgbBlue+=0x20;
    if(rgbQuad.rgbGreen <= 0xef)rgbQuad.rgbGreen+=0x10;
    if(rgbQuad.rgbRed <= 0xef)rgbQuad.rgbRed+=0x10;
    *lpRowTgt=(BYTE)
    (
    (0x00c0&rgbQuad.rgbBlue) |
    ((0x00e0&rgbQuad.rgbGreen)>>2) |
    ((0x00e0&rgbQuad.rgbRed)>>5)
    );
    }
    else
    {
    for(n=0; n<arRgbQuad.GetSize(); n++)
    {
    if
    (
    !memcmp
    (
    (LPSTR)&rgbQuad,
    (LPSTR)arRgbQuad[n],
    sizeof(RGBQUAD)
    )
    )break;
    }
    *lpRowTgt=(BYTE)n;
    }
    lpRowSrc+=3;
    lpRowTgt++;
    }
    }
    ::GlobalUnlock(m_hDIB);
    ::GlobalFree(m_hDIB);
    ::GlobalUnlock(hDIB);
    m_hDIB=hDIB;
    m_nBmpFormat=BMP_FORMAT_256COLOR;
    while(arRgbQuad.GetSize())
    {
    delete (LPRGBQUAD)arRgbQuad.GetAt(0);
    arRgbQuad.RemoveAt(0);
    }
    pos=GetFirstViewPosition();
    ptrView=(CGDIView *)GetNextView(pos);
    ASSERT(ptrView->IsKindOf(RUNTIME_CLASS(CGDIView)));
    ptrView->LoadBitmap(m_hDIB);
    AfxGetApp()->DoWaitCursor(FALSE);
    }