First:
HBITMAP CXTPGraphicBitmapPng::ConvertToBitmap(BYTE* pbImage, CSize szImage, int cImgChannels) const
{
.
.
.
bmi.bmiHeader.biBitCount = 32; // Here the destination bitmap will be created 32bits even the source png is not 32bits.
.
.
.
// copy image to screen
for (yImg = 0; yImg < szImage.cy; yImg++)
{
src = pbImage + yImg * wImgRowBytes;
dst = pBits + yImg * wDIRowBytes;
for (xImg = 0; xImg < szImage.cx; xImg++)
{
r = *src++;
g = *src++;
b = *src++;
*dst++ = b;
*dst++ = g;
*dst++ = r;
a = 0;
if (cImgChannels == 4) // Else (cImgChannels != 4), a = 0, so all the destination bitmap alpha bytes will be 0 (the destination bitmap will draw transparent).
{
a = *src++;
}
*dst++ = a;
}
}
.
.
.
}
And a call to the function
BOOL CXTPGraphicBitmapPng::LoadFromFile(CFile* pFile)
{
.
.
.
m_bAlpha = (cImgChannels == 4); // Asumming (cImgChannels != 4). So m_bAlpha = FALSE.
.
.
.
}
Will cause
AFX_INLINE BOOL CXTPGraphicBitmapPng::IsAlpha() const {
return m_bAlpha;
}
returning FALSE, and actually
bmi.bmiHeader.biBitCount = 32; // The destination bitmap is created 32bits.
=======================================================
Second:
HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromFile(LPCTSTR lpszFileName, BOOL* lbAlphaBitmap)
{
.
.
.
HBITMAP hBmp = (HBITMAP)LoadImage(0, lpszFileName, IMAGE_BITMAP, 0, 0,
LR_DEFAULTSIZE | (bAlphaBitmap ? LR_CREATEDIBSECTION : 0) |
LR_LOADFROMFILE); // LoadImage here is always returning 32bits bitmaps even they are 24, 16, 8, 4 or monochrome.
.
.
.
}
LoadImage is working right outside CXTPImageManagerIcon::LoadBitmapFromFile function
The same problem about LoadImage function for the below functions:
HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromResource(LPCTSTR lpszResource, BOOL* lbAlphaBitmap)
HBITMAP AFX_CDECL CXTPImageManagerIcon::LoadBitmapFromResource(HMODULE hModule, LPCTSTR lpszResource, BOOL* lbAlphaBitmap)
Finally:
This is the correct CXTPGraphicBitmapPng::ConvertToBitmap function that should be
HBITMAP CXTPGraphicBitmapPng::ConvertToBitmap(LPBYTE lpbytImage, CSize szImage, int iImgChannels) const { BITMAPINFO bmi; // Initialize header to 0s. ::ZeroMemory(&bmi, sizeof(BITMAPINFO)); // Fill out the fields you care about. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = szImage.cx; bmi.bmiHeader.biHeight = -szImage.cy; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = (WORD)(iImgChannels == 4 ? 32 : 24); bmi.bmiHeader.biCompression = BI_RGB; HBITMAP hBitmap; LPBYTE lpbytBits; hBitmap = ::CreateDIBSection(::CreateCompatibleDC(NULL), &bmi, DIB_RGB_COLORS, (LPVOID*)&lpbytBits, NULL, 0); if (hBitmap == NULL) return NULL; // Copy image LPBYTE lpbytSrc, lpbytDst; lpbytSrc = lpbytImage; lpbytDst = lpbytBits; for (int i = 0; i < szImage.cy; i ++) { for (int j = 0; j < szImage.cx; j ++) { lpbytDst[0] = lpbytSrc[2]; lpbytDst[1] = lpbytSrc[1]; lpbytDst[2] = lpbytSrc[0]; if (iImgChannels == 4) lpbytDst[3] = lpbytSrc[3]; lpbytSrc += iImgChannels; lpbytDst += iImgChannels; } if (iImgChannels == 3) lpbytDst += -(szImage.cx * 3) & 3; } return hBitmap; }
And the LoadImage implementation that should be
(HBITMAP)::LoadImage(NULL, lpszFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE); // For files.
And
(HBITMAP)::LoadImage(hModule, lpszResource, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // For resources.
Thank you for your understand ;)
------------- Product: Codejock ToolkitPro MFC v16.2.0 Platform: Microsoft Windows 8 Pro (64-bit)
Language: Microsoft Visual C++ v6.0 (MFC)
|