我正在尝试使用alpha拉伸HBITMAP并将其绘制到anther hdc。
我正在使用StretchDIBits然后使用AlphaBlend,如下面的代码所示。
问题是AlphaBlend失败并返回false 1.有谁知道可能是什么原因? 2.有更好的原因来拉伸和绘制透明图像吗?
void AnimationManager::Draw(HDC hBBDC, Instance sInstance,RECT sClientRect)
{
// sClientRect is the hwnd rect
int nID = GetId(sInstance.nAnemationId);
int nFrameindex = sInstance.nFrameIndexs;
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
///******************* create PBITMAPINFO *********************///
GetObject(m_pAnimations[nID]->m_pFramesArray[nFrameindex]->hBmp, sizeof(bmp), &bmp);
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if(cClrBits == 1)
cClrBits = 1;
else if(cClrBits <= 4)
cClrBits = 4;
else if(cClrBits <= 8)
cClrBits = 8;
else if(cClrBits <= 24)
cClrBits = 24;
else cClrBits = 32;
if(cClrBits != 24)
pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<cClrBits));
else
pbmi = (PBITMAPINFO)LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if(cClrBits < 24)
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31)& ~31)/8 * pbmi->bmiHeader.biHeight;
pbmi->bmiHeader.biClrImportant = 0;
///**************************end PBITMAPINFO creation *****************************************///
// I checked the code to this point and it seems to be fine. The problem stasrts here:
///create a pointer to the image bits
LPVOID lpvBits = (LPVOID)LocalAlloc(GPTR,pbmi->bmiHeader.biSizeImage);
GetBitmapBits(m_pAnimations[nID]->m_pFramesArray[nFrameindex]->hBmp, pbmi->bmiHeader.biSizeImage, lpvBits);
///stretch
bool test = StretchDIBits(hdcMem,0,sClientRect.bottom,sClientRect.right, -1*sClientRect.bottom,0,0,pbmi->bmiHeader.biWidth,pbmi->bmiHeader.biHeight, lpvBits,pbmi,DIB_RGB_COLORS, SRCCOPY);
///blend
test = AlphaBlend(hBBDC,0,0,sClientRect.right, sClientRect.bottom,hdcMem,0,0,sClientRect.right,sClientRect.bottom,m_sBlendfunc);
test = DeleteDC(hdcMem); // after CreateCompatibleDC
test = ReleaseDC(NULL, hdcScreen); // after GetDC
LocalFree(pbmi);
LocalFree(lpvBits);
}
答案 0 :(得分:0)
如果StretchDIBits
也能伸展,为什么要使用AlphaBlend
?
答案 1 :(得分:0)
我不能确切地说代码失败的原因,但我从最近的经验中知道AlphaBlend对它接受的位图格式非常挑剔。幸运的是,我可以提供一些适用于其他情况的工作代码。
static void DrawBitmapWithAlpha(HDC aDeviceContext,const CartoType::TBitmap* aBitmap,const CartoType::TRect& aDestRect,const CartoType::TRect& aSourceRect)
{
HDC hdc = CreateCompatibleDC(aDeviceContext);
BITMAPINFOHEADER bitmap_header;
memset(&bitmap_header,0,sizeof(bitmap_header));
bitmap_header.biSize = sizeof(BITMAPINFOHEADER);
bitmap_header.biWidth = aBitmap->Width();
bitmap_header.biHeight = aBitmap->Height();
bitmap_header.biPlanes = 1;
bitmap_header.biBitCount = 32;
bitmap_header.biCompression = BI_RGB;
bitmap_header.biSizeImage = 0;
bitmap_header.biXPelsPerMeter = 1000;
bitmap_header.biYPelsPerMeter = 1000;
bitmap_header.biClrUsed = 0;
bitmap_header.biClrImportant = 0;
void* bitmap_data = NULL;
HBITMAP hbitmap = CreateDIBSection(hdc,(const BITMAPINFO*)&bitmap_header,DIB_RGB_COLORS,&bitmap_data,NULL,0);
// Reflect the data vertically and change from ABGR to BGRA.
unsigned char* dest_row = (unsigned char*)bitmap_data;
const unsigned char* source_row = aBitmap->Data() + (aBitmap->Height() - 1) * aBitmap->RowBytes();
for (int y = 0; y < aBitmap->Height(); y++, dest_row += aBitmap->RowBytes(), source_row -= aBitmap->RowBytes())
{
const unsigned char* p = source_row;
unsigned char* q = dest_row;
unsigned char* end = q + aBitmap->RowBytes();
while (q < end)
{
*q++ = p[1];
*q++ = p[2];
*q++ = p[3];
*q++ = p[0];
p += 4;
}
}
SelectObject(hdc,hbitmap);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0xFF;
bf.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(aDeviceContext,aDestRect.Left(),aDestRect.Top(),aDestRect.Width(),aDestRect.Height(),
hdc,aSourceRect.Left(),aSourceRect.Top(),aSourceRect.Width(),aSourceRect.Height(),
bf);
DeleteObject(hbitmap);
DeleteDC(hdc);
}
可以轻松更改“垂直反映数据”部分,以便将位图数据复制到CreateDIBSection创建的位图中。
我的位图格式与Windows兼容,因为它的行字节数总是相同的;如果您的位图格式没有该属性,则需要更改代码以相应地复制数据。
另一个有用的观点:我无法使用bitfields;我还怀疑你必须提供一个压缩设置为BI_RGB的32bpp位图。