|
When you do the pre-multiply, you must make sure that no color channel is greater than the alpha channel. Otherwise there can be a glitch in the colors. Oddly, this only affects 64-bit versions of Windows.
|
|
|
|
|
I realize that there is apparently an update in Borland C++ 6.0 that adds properties to the TForm class named AlphaBlend and AlphaBlendValue that enable transparent forms. What I 'REALLY' want to do is to add a transparent MASK to a standard TForm so that it is transparent outside of the MASK and opaque inside. I'm wondering if anyone has any suggestions as to how this could be implemented.
|
|
|
|
|
|
Only a copy of MSDN manual
|
|
|
|
|
AlphaBlend function draws over the existing background. I return FALSE in OnEraseBkGrnd(). Still it does not erase the background. Gradually losing its transparency.
here is the code:
BLENDFUNCTION bfn;
bfn.BlendOp = AC_SRC_OVER;
bfn.BlendFlags = 0;
bfn.SourceConstantAlpha = 100;
bfn.AlphaFormat = AC_SRC_ALPHA;
pCdc->AlphaBlend(0, 0, rc1.Width(), rc1.Height(), &memCDC, 0, 0, rc1.Width(), rc1.Height(), bfn);
|
|
|
|
|
It sounds like you are almost certainly not erasing the background.
|
|
|
|
|
Dear Sir,
I modify your sample code to let the form can be moved.
I set the fix value like "SourceConstantAlpha = 185";
And set the bitmap with all dark.
I run the sample, the graphic is always dark.
I think the CClientDC is not release completed, and the next paint is coming.
I research the CClientDC, the document said it will destory automatically.
But the program run is wrong.
Do you have any idea to fix this problem?
Thanks.
-- modified at 4:20 Friday 17th August, 2007
|
|
|
|
|
Hi fellow coders,
When I'm blending pixels ARGB 127,127,127,127 on pixel RGB 0,0,127 the result is surprisingly RGB 127,127,190 !! where I was waiting for a result of 63,63,127.
AlphaBlend is using the formula :
A1R1G1B1 blended on R2G2B2 = ( R1 + A1*R2 ), ( G1 + A1*G2 ), ( B1 + A1*B2 )
How can I have it working with the formula :
A1R1G1B1 blended on R2G2B2 = ( A1*R1 + (255-A1)*R2 ), ( A1*G1 + (255-A1)*G2 ), ( A1*B1 + (255-A1)*B2 )
I'm using the following code :
CImage MyImage;<br />
CClientDC dc ( MyMFCControl );<br />
_pDoubleBufferBitmap = new CBitmap();<br />
_pDoubleBufferBitmap -> CreateCompatibleBitmap ( &dc, ... );<br />
_pDoubleBufferCDC = new CDC();<br />
_pDoubleBufferCDC -> CreateCompatibleDC(&dc);<br />
_pDoubleBufferCDC -> SelectObject(_pDoubleBufferBitmap);<br />
CPaintDC* pPaintDC = CreateCompatibleDC ( dc );<br />
MyImage.AlphaBlend ( _pPaintDC -> m_hDC, 50,50, 0xFF, AC_SRC_OVER );
Thank you for any help..
Alexis.
|
|
|
|
|
Oh.. ok I got it now.
The MSDN was not clear enough for me about the need of an alpha pre multiplyed ARGB format .
Alexis.
|
|
|
|
|
I translated this into C#. Works like a charm! Infinitely faster than DrawImage and the like in .NET.
I simply didnt know about this function. Thanks for pointing it out!
|
|
|
|
|
Hi.
I have a problem with the AlphaBlend function, that is the rendered bitmap doesn't look like it should.
For example, a bitmap with a pure red opaque region (a = 255, r = 255, g = 0, b = 0) and transparent in rest looks very weird: on a white background it's completly transparent, on a blue background the red region is magenta, etc. It looks like the Alphablend adds with saturation the coresponding channels of the colors.
The bitmap is obtained from a tiff image, edited with Photoshop.
Here is a part of the source code:
//premultiply the pixels of the bitmap
for (int i = 0; i < m_bm.Width(); i++)
{
for(int j = 0; j < m_bm.Height(); j++)
{
GX_RGBA c = m_bm.ReadPixel(i, j);
c.r = (BYTE)((double)c.r * c.a / 255.);
c.g = (BYTE)((double)c.g * c.a / 255.);
c.b = (BYTE)((double)c.b * c.a / 255.);
m_bm.WritePixel(i, j, c);
}
}
//call AlphaBlend
CDC memDC;
memDC.CreateCompatibleDC(NULL);
CBitmap *oldBmp = memDC.SelectObject(CBitmap::FromHandle(hBmp));
if (pBm->Type() == colour32)
{
BLENDFUNCTION bld;
bld.BlendOp = AC_SRC_OVER;
bld.BlendFlags = 0;
bld.SourceConstantAlpha = 255;
bld.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(*dp.pDC, outputOrigin.x, outputOrigin.y, m_bitmap.Width(), m_bitmap.Height(), memDC, 0, 0, m_bitmap.Width(), m_bitmap.Height(), bld);
}
Any insights will be very appreciated, thank you.
/\
|
|
|
|
|
Hey,
Try this if you haven't already figured it out:
bld.AlphaFormat = 0;
I had the same problem and setting bld.AlphaFormat to 0 seemed to fix it.
|
|
|
|
|
When you do the pre-multiply, you must make sure that no color channel is greater than the alpha channel. Oddly, this only affects 64-bit versions of Windows.
|
|
|
|
|
Can i draw with a single call of AlphaBlend image with alpha and transparency or should I call TransparentBlt and then AlphaBlend?
If the first one is true, please show me a sample code 
|
|
|
|
|
I've been looking all over the Internet for an explanation of this and this is the only article.
Thank you Woo Seok Seo!
|
|
|
|
|
really?
i have seen several AlphaBlend?
|
|
|
|
|
Oh, well, I didn't find it and it doesn't diminish how awesome this article was! 
|
|
|
|
|
Where can I find the same demo but I want that it is normal window???
|
|
|
|
|
You can find code for the alphablend algorithm that will run on Windows 95 here:
http://www.windevnet.com/documents/s=7628/wdj0109b/0109b.htm
|
|
|
|
|
Unfortunately, that algorithm is not nearly as fast as the Windows one, which probably is written in assembly.
I'm actually looking for an alpha-blending algorithm to be used in a moderately intensive graphics application involving lots of animation, an algorithm that's fast and works with all versions of Windows, msimg32.dll is probably the best bet but I'm not completely certain that it could be used with Win95/NT. Would appreciate any info from someone who has tested it with those OS's.
Henry P.
http://www.allersoft.com
|
|
|
|
|
How much slower is it?
On my machine, the code is actually faster. (I must be doing something wrong)
I'm using DoAlphaBlend for XP menu, toolbar effects and for "softening" lines and text in the main view of the program. I took a little shortcut in Christian's algorithm: Since I know the background (destination) is always the same colour (i.e. all bits the same RGB value), why bother creating 2 DIBs? I simply create 1 DIB in the algorithm, and then apply the alphablend between the source DIB bits and a static background colour.
I also ignore any source bit that is the same colour as the background color. This acts like a transparency for background coloured bits in the source.
|
|
|
|
|
Actually, the Windows AlphaBlend function has variable speeds depending on the specific parameters it's given. If you blend two bitmaps that are compatible with each other, it is MUCH faster than blending two bitmaps that are incompatible. For instance, if you're trying to blend a 24-bit bitmap to a 16-bit surface, it's a lot slower than blending a 16-bit bitmap to a 16-bit surface.
This difference is probably insignificant when you're dealing with bitmaps of menu size. However, when you're blending a bitmap, measuring say 800x600 pixels, that's almost half a million pixels that you have to compute the composite color for. That is too slow on most current home computers to be of use in an animation application.
I've found that blending two compatible bitmaps using the Windows AlphaBlend is amazingly fast, whereas blending two incompatible bitmaps (say a 32-bit DIB with a 16-bit surface) is MUCH slower (perhaps by an order of magnitude?).
Incidentally, if you include the msimg32.dll from WinME (and probably 98 as well) - but not the one from Win2000/XP - the AlphaBlend function will work on Win NT4. I haven't tested it on a Win95 machine yet (hard to find one these days) but I think it should work well as well (When you examine the import table for the WinME msimg32.dll, it contains only function calls to "basic" GDI functions that are available on all Windows platforms, so it probably will work on all Windows platform).
|
|
|
|
|
For the testing, I'm using the AlphaBlend on the entire view of an SDI project. (1280 x 1024, minus scrollbar space)
Here's the code I'm using in my OnDraw function.
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CRect rcClient;
GetClientRect(&rcClient);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
CBitmap* pOldBmp = memDC.SelectObject(&bmp);
memDC.FillSolidRect(&rcClient, GetSysColor(COLOR_WINDOW));
BLENDFUNCTION bf =
{
AC_SRC_OVER,
0,
170,
0
};
// Output text and lines here.
// Perform the blend
AlphaBlend(pDC->GetSafeHdc(), rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), memDC.GetSafeHdc(), rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), bf);
memDC.SelectObject(pOldBmp);
Am I doing something that is not optimal for the SDK based function? Christian's algorithm, combined with the tweaks I mentioned in a previous article, result in roughly 3x faster drawing code.
|
|
|
|
|
I've created an SDI project, and paste the code you provide into the CMyView::OnDraw function. I changed the color of the memDC to red to make the painting more easily observable. I did not do a formal timing test, but by resizing the view, the repainting occurs much quicker with the Windows AlphaBlend as compared to Christian's AlphaBlendU. The former repainting is almost instanstaneous whereas the latter pauses (the background takes on the original white color for a split second) before the painting is completed.
This test was done on a AMD 1.8GHz with WindowsXP, 512MB RAM. This could be a system-specific finding.
The Windows AlphaBlend function actually allows two different blending modes, by specifying the last parameter (AlphaFormat) of the BLENDFUNCTION struct. For reference:
typedef struct _BLENDFUNCTION
{
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
If AlphaFormat is 0, the source image is assumed to have a constant alpha as specified by SourceConstantAlpha. If AlphaFormat is AC_SRC_ALPHA, the source image is assumed to contain individual alpha values for each pixel (the alpha value being contained in the fourth byte of each pixel in a 32-bit (4 bytes per pixel) bitmap.
The reason I bring this up is because I've found that, at least for several computer systems I've tried on (both AMD, WinXP and Win2000), the blending is SIGNIFICANTLY faster when AlphaFormat is 0 (comparable to a BitBlt of the same bitmap size), whereas when the AlphaFormat is AC_SRC_ALPHA, the speed is slower, comparable to Christian's algorithm.
My speculation is that for the case where AlphaFormat is 0 (i.e., only a single SourceConstantAlpha is used), the Windows function does not need to extract the device-independent bits, and rather operate directly on the device-dependent bitmaps. The Windows function may also take advantage of driver acceleration as well...but this is just speculation.
If anyone discovers other interesting findings, please post them here.
Henry P.
http://www.allersoft.com
|
|
|
|
|
Hi guys
someone have a working version of this algo ?
I tried it, but got nothing 
|
|
|
|
|