Click to See Complete Forum and Search --> : Alpha Blending (Resolved & Updated)
lnelsestuen
Nov 3rd, 2002, 11:56 AM
I was looking for a way to alpha blend a form (translucency, ie see-tru, not transparency) but was unable to find actual code that I thought worthy; so I made my own. It's kind of slow (calculating and drawing 38,912 pixels (152x256) takes an average of 3,305+-13ms using the Point method of 2 source PictureBoxes and 1 destination PictureBox) but it gives the desired effect. It's like stitching two images together. Attatched is my sample program that I am working on. It allows you to choose two source images (.bmp's) and create a third alpha blended picture with adjustable transparency. As I mentioned before, the code works good, but somewhat slowly (without drawing it takes 1,370+-2ms for 38,912 pixels (152x256) using the Point method). Take a look and tell me what you think.
Another reason for this test is because I have WinME and I can't use SetLayeredWindowAttributes. This code does not make the form translucent but it is a step in the right direction (I feel). I am also wondering if using GetBitmapBits and SetBitmapBits could cut down the calculation and drawing times. If you come up with any improvements, please let me know so I can utilize them and improve my process.
PS - If you do reply, do not e-mail me. My Hotmail Junk Filter is on exclusive (no one in my Contacts or Safe List gets to my Inbox) and Immediate Deletion (anything going to go to my Junk Mail folder is immediately deleted) so I will not recieve your e-mail. Either post a reply or send a Private Message.
Attatchment deleted
Electroman
Nov 3rd, 2002, 12:52 PM
Using the point as Pset method is the slowest method second is SetPixelV and GetPixel then its SetPixel and GetPixel and The fastest method would be to use a pointer. I have to say sorry for keep posting this but it quite simply is 10 -15 times faster.
I made a well commented Example which your welcome to download from http://www.Electroman.co.uk/VBExamples/FastPixelEditing.zip it explains how to use a pointer to edit a picture Pixel by Pixel in a byte array. I belive to Alpha blend the formula is:FinalPixel = (AlphaValue * (Source + 256 - Destination)) / 256 + Destination - AlphaValue Source, Destination + FinalPixel are each the colors for each pixel.
lnelsestuen
Nov 3rd, 2002, 02:13 PM
I found a (somewhat) successful way using GetBitmapBits and SetBitmapBits takes an average of 14+-0ms (slightly faster than PSet) to calculate and draw the alpha blended picture. The problem is, if you are viewing the BMP Bits picture and switch to another window (one that covers up the alpha blended picture) and back, it displays the portion of the window that covered it up. My PictureBoxes have AutoRedraw=True and I use the Picture property to display the alpha blended result. Why am I getting this wierd "ghosting?" Attatched is the updated sample program with the BMP Bits feature.
I belive to Alpha blend the formula is:
I am using formulas from the MSDN in the description of the BLENDFUNCTION type which are as follows:
Dst.Red=Src1.Red*ConstantAlpha+(1-ConstantAlpha)*Src2.Red
Dst.Green=Src1.Green*ConstantAlpha+(1-ConstantAlpha)*Src2.Green
Dst.Blue=Src1.Blue*ConstantAlpha+(1-ConstantAlpha)*Src2.Blue
where ConstantAlpha is the transparency percentage (as a decimal, ie 50% transparency=50/100=.5)
As I mentioned in my first post, these formulas do work. And using the GetBitmapBits and SetBitmapBits gives HUGE TIME IMPROVEMENT, but I get the wierd "ghosting" when switching to another window.
Any suggestions?
Attatchment deleted
Sastraxi
Nov 3rd, 2002, 06:33 PM
If you are developing for Win2k/XP, these have partial blending functions built in. And when you get focus, use the Refresh method of your pictureboxes.
lnelsestuen
Nov 3rd, 2002, 08:06 PM
Originally posted by Sastraxi
If you are developing for Win2k/XP, these have partial blending functions built in. And when you get focus, use the Refresh method of your pictureboxes.
As I mentioned in my first post, I have WinME so the blending functions (ie SetLayeredWindowAttributes) are not available.
Sastraxi
Nov 3rd, 2002, 09:17 PM
Sorry, didn't see that. Did the refresh bit help with the applications over your form problem?
lnelsestuen
Nov 3rd, 2002, 10:31 PM
No. I found some major underlying problems. Technically my code for the GetBitmapBits and SetBitmapBits actually doesn't work:mad:. One major problem is that the bitmaps aren't the same size and therefore the algorithm combines bits that shouldn't be combined. Major tweaking to be done. Thanks anyway.
You can still check out the attatchment from my first post to see the working code using the Point & PSet methods. Like I said, it's slow, but it actually works.
jmiller
Nov 3rd, 2002, 10:45 PM
i'm not sure if this works with ME, but there is an api function called AlphaBlend
lnelsestuen
Nov 4th, 2002, 09:31 PM
Originally posted by jmiller
i'm not sure if this works with ME, but there is an api function called AlphaBlend
Accroding to AllAPI.net 's API-Guide, it is available on WinME (and according to MS Visual Studio's Dependency Viewer, it is there). I tried it once and couldn't get it to work, but I didn't play with it much. It might work, but I didn't take the time to debug my simple test. Thanks for reminding me, though. I forgot about it but I think I will play with it for a while.
Sastraxi
Nov 4th, 2002, 10:49 PM
You have to jam in a complicated struct. Go to allapi.net and look around there, and it'll show you how to return the pointer to the struct to the function (blendparams I think).
jmiller
Nov 4th, 2002, 10:59 PM
i've used it once, based on the example used in allapi.net's tutorial, and got it to work, and i think the UDT has just four items, but you have to convert it to a long using another API (CopyMemory, i think). otherwise, its parameters are fairly similar to bitblt, if you know that one
Sastraxi
Nov 4th, 2002, 11:07 PM
Yes, that's right, not VarPtr but CopyMemory... Anyway, it's very fast, once you have it you shouldn't have any troubles..
lnelsestuen
Nov 6th, 2002, 12:39 AM
GOT IT TO WORK. I used the same example from API-Guide (they actually use RtlMoveMemory, basically the same as CopyMemory). The reason I couldn't get it to work before is because of the ByRef argument:
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, _
ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, _
ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, _
ByVal lInt As Long, ByRef BLENDFUNCT As BLENDFUNCTION) As Long
'examining the API-Guide example, they use the declaration
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, _
ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, _
ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, _
ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
Apparently the AlphaBlend function does not work with ByRef BLENDFUNCT. I don't know why, but I know that when I changed my declaration (and used RtlMoveMemory to copy the BLENDFUNCTION parameters to a long) that the AlphaBlend function works. I made a different program to test AlphaBlend (which now works) and TransparentBlt. It's a pretty bare program, but now I know (and you can find out) how to use it.
The code isn't commented, but I think most of you should be able to figure it out. If you have a question, just post it.
lnelsestuen
Nov 6th, 2002, 12:51 AM
I deleted the previous attatchments because they were junk and didn't need to be wasting space on the server. Also, when I was debugging my algorithms using Get/SetBitmapBits, I found that it was (at first) actually only calculating 1 or 2 pixels, not the entire picture. When it was finally calculating the full picture, it took about half a second to do, but as I mentioned in an earlier post, it was combining bits that shouldn't have been combined, so the picture looked a little funky. If you are still interested in the Point/PSet methods I described (for understanding how alpha blending works, what it is, etc), just give me a hollar.
Sastraxi
Nov 10th, 2002, 12:59 PM
I was looking at your alphablending algorithm and i must give you a 'tut, tut' for that. You see, there's a much faster way of doing it: TempR = (aRGB.R * CLng(sRGB.R + 256 - dRGB.R)) / 256 + dRGB.R - aRGB.R
TempG = (aRGB.G * CLng(sRGB.G + 256 - dRGB.G)) / 256 + dRGB.G - aRGB.G
TempB = (aRGB.B * CLng(sRGB.B + 256 - dRGB.B)) / 256 + dRGB.B - aRGB.BaRGB is the alpha (0 to 255), sRGB is the source (0 to 255), and dRGB is the destination (0 to 255). Doing it this way works much faster because there is only one division and it never uses floating point numbers.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.