具有透明加载形式 PNG 的 MFC Draw Icons 图像显示为灰色

MFC Draw Icons images with transparency loaded form PNG are displayed greyish

我正在尝试显示来自 PNG 条带的加载图标。问题是由于透明度因素,它们显示为灰色。我不知道为什么,因为背景是白色的。 这是一个代码片段:

class CPslToolBarImages : public CMFCToolBarImages
{
public:
    CPslToolBarImages() { m_sizeImageDest.cx = m_sizeImageDest.cy = 32; }
    ~CPslToolBarImages() {}
public:
    BOOL ToImageList(CImageList *imagelist);

};

BOOL CPslToolBarImages::ToImageList(CImageList *imagelist)
{
    CSize size = GetImageSize();

    imagelist->Create(size.cx, size.cy, ILC_COLOR32 | ILC_MASK, 0, 0);

    HBITMAP hbmImageWellCopy = (HBITMAP) ::CopyImage(m_hbmImageWell, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);

    imagelist->Add(CBitmap::FromHandle(hbmImageWellCopy), m_clrTransparent == -1 ? afxGlobalData.clrBtnFace : m_clrTransparent);

    extern void AFXAPI AfxDeleteObject(HGDIOBJ* pObject);
    AfxDeleteObject((HGDIOBJ*)&hbmImageWellCopy);
    return TRUE;

}


BOOL PlMakeHighColorImageList(CImageList *imagelist, LPCTSTR resid, CSize sizeImage)
{
    CPslToolBarImages images;
    images.SetImageSize(sizeImage);
    images.LoadStr(resid);

    return images.ToImageList2(imagelist);

}

// Draw call
CImageList imagelist;
PlMakeHighColorImageList(imagelist, "ImageStrip.PNG", CSize(16, 16));
imagelist.Draw(dc, nImage, rc.TopLeft(), ILD_TRANSPARENT);

我注意到当我从 PNG 中读取它们时,像素值已经与 alpha 通道混合,所以我对它们进行了反向操作。

static BYTE computeColor(int color, int alpha)
{
    if (alpha == 0)
        return 0;
    int result = 255 * color / alpha;

    return (result > 255) ? 255 : (result < 0) ? 0 : result;
}

void MyClass::ComputeColorWithAlphaChannel(HBITMAP hbmImageWellCopy)
{
    HDC hDC = GetDC(0);

    BITMAP bm = { 0 };
    GetObject(hbmImageWellCopy, sizeof(bm), &bm);
    BITMAPINFO* bmi = (BITMAPINFO*)_alloca(sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)));
    ::ZeroMemory(bmi, sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)));
    bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    BOOL bRes = ::GetDIBits(hDC, hbmImageWellCopy, 0, bm.bmHeight, NULL, bmi, DIB_RGB_COLORS);
    if (!bRes || bmi->bmiHeader.biBitCount != 32) return;
    LPBYTE pBitData = (LPBYTE) ::LocalAlloc(LPTR, bm.bmWidth * bm.bmHeight * sizeof(DWORD));
    if (pBitData == NULL) return;
    LPBYTE pData = pBitData;
    ::GetDIBits(hDC, hbmImageWellCopy, 0, bm.bmHeight, pData, bmi, DIB_RGB_COLORS);
    for (int y = 0; y < bm.bmHeight; y++) {
        for (int x = 0; x < bm.bmWidth; x++) {
            pData[0] = computeColor(pData[0], pData[3]);
            pData[1] = computeColor(pData[1], pData[3]);
            pData[2] = computeColor(pData[2], pData[3]);
        }
    }
    ::SetDIBits(hDC, hbmImageWellCopy, 0, bm.bmHeight, pBitData, bmi,        DIB_RGB_COLORS);
    ::LocalFree(pBitData);
}