【发布时间】:2016-01-01 21:08:50
【问题描述】:
我有 2 个缓冲区指向不同大小的 RGB32 图像,所以我的想法是缩放一个缓冲区以匹配另一个缓冲区并对这些图像进行 alphablend。
目前,我能够将 StretchBlt(用于缩放性能)和 GDI+ drawimage 函数与用于 alphablending 的颜色矩阵混合。这似乎有点慢,而且使用 DirectX 的不同组件使用缓冲区也存在问题。对于缓冲区问题,我尝试以相反的顺序复制行,但它在 DirectX 相关组件中除外。
Bitmap bmp1(width, height, 4bytesperpixel, RGB32, bufferpointer1);
Bitmap blend(width, height, 4bytesperpixel);
Graphics g(&newbmp)
using GDI function
Bitmap bmp2(scaleWidth, scaleHeight, 4bytesperpixel, RGB32, bufferpointer2)
HDC memdc = g.GetHDC();
//// scaling the bufferpointer2 to actual width & height
StretchDIBits(memdc, x,y, width, height, 0, 0,scaleWidth, scaleHeight, bufferpointer2,..)
g.ReleaseDC(memdc); // so that content is copied to the bitmap
//// Then alphablending bmp1 on top of the scaled imaged bmp2
//// Using lockbits to copy the bitmap bytes and unlocking it.
所以我需要替换 GDI+ 函数并为此使用像 AlphaBlend 这样的 Win32 函数。我试过这样的东西,它显示一个黑屏
BITMAPINFO bminfo1 = {};
bminfo1.bmiHeader.biSize = sizeof( BITMAPINFO );
bminfo1.bmiHeader.biWidth = w;
bminfo1.bmiHeader.biHeight = h;
bminfo1.bmiHeader.biBitCount = m_nBytesPerPixel * 8;
bminfo1.bmiHeader.biCompression = BI_RGB;
bminfo1.bmiHeader.biPlanes = 1;
BITMAPINFO bminfo2 = {};
bminfo2.bmiHeader.biSize = sizeof( BITMAPINFO );
bminfo2.bmiHeader.biWidth = sW;
bminfo2.bmiHeader.biHeight = sH;
bminfo2.bmiHeader.biBitCount = m_nBytesPerPixel * 8;
bminfo2.bmiHeader.biCompression = BI_RGB;
bminfo2.bmiHeader.biPlanes = 1;
char* pBytes1, *pBytes2;
HDC hmemdc1 = CreateCompatibleDC(GetDC(0));
HDC hmemdc2 = CreateCompatibleDC(GetDC(0));
HBITMAP hBitmap1 = CreateDIBSection(hmemdc1, &bminfo1, DIB_RGB_COLORS, (void**) &pBytes1, NULL, 0);
SetDIBits(hmemdc1, hBitmap1, 0, bminfo1.bmiHeader.bih, pBuffer[0], &bminfo1, DIB_RGB_COLORS);
HBITMAP hBitmap2 = CreateDIBSection(hmemdc2, &bminfo2, DIB_RGB_COLORS, (void**) &pBytes2, NULL, 0);
SelectObject(hmemdc2,hBitmap2);
StretchDIBits(hmemdc2, 0, 0, w, h, 0, 0,
sW, sH, pBuffer[1], &bminfo2, DIB_RGB_COLORS, SRCCOPY );
BLENDFUNCTION bStruct;
bStruct.BlendOp = AC_SRC_OVER;
bStruct.BlendFlags = 0;
bStruct.SourceConstantAlpha = 255;
bStruct.AlphaFormat = AC_SRC_ALPHA;
SelectObject(hmemdc1,hBitmap1);
SelectObject(hmemdc2,hBitmap2);
//blend bmp2 on bmp1
BOOL res = AlphaBlend(hmemdc1, 0, 0, w, h, hmemdc2, 0, 0, w, h, bStruct);
//for testing output
SelectObject(hmemdc1,hBitmap1);
BitBlt(GetDC(0),0,0,width,height,hmemdc1,100,100,SRCCOPY);
//copy the bitmap buffer
memcpy(out, pBytes1, (w * m_nBytesPerPixel) * h);
我不确定是否可以使用 AlphaBlend 函数来混合基于 2 个内存 DC 的每个像素的位图。任何帮助将不胜感激。
【问题讨论】:
-
请出示真实代码。目前无法判断您是否忘记了一些简单的事情(例如,您没有表明您选择
hBitmap1到hmemdc1)或者是否还有更多内容。 -
AlphaBlend 肯定会在两个内存位图上工作。我会检查 StretchDIBits 的结果,并且你已经正确设置了 blendfunction 参数
-
@JonathanPotter 我已经编辑以添加完整的代码。 gordy,使用的 StretchDIBits 和 Bitblt 函数按预期工作
-
SetDIBits用于 DDB,但hBitmap1是 DIB - 不确定这是否可行。你可以试试SetDIBitsToDevice。如果您使用AC_SRC_ALPHA,您就是在告诉GDI 源位图有一个(预倍增的)alpha 通道。可以?m_nBytesPerPixel的值是多少? -
其他问题包括
BitBlt(GetDC(0), ...,这是一个明显的资源泄漏。