'these if is for be changed
If blnTransparentImage = True Then
Dim BF As Long
Const USE_BITMAP_ALPHA = &H1000000 'AC_SRC_ALPHA scaled up to the 4th byte of a long
BF = 128 * &H10000 'semi transparent ignoring bitmaps alpha channel
BF = 255 * &H10000 Or USE_BITMAP_ALPHA 'fully opaque using bitmaps alpha channel
picGraphicsEffects.Picture = UserControl.Image
AlphaBlend UserControl.hdc, 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight, picGraphicsEffects.hdc, 0, 0, picGraphicsEffects.ScaleWidth, picGraphicsEffects.ScaleHeight, BF
End If
'the next line is need too... when the shadow is desactivated
UserControl.Picture = UserControl.Image
PicAnimation(0).Tag = ""
Call SubTransparent 'these sub is for put 1 color(backcolor) hide
RaiseEvent ChangeImage(lngActualSubImage)
and theres the result(in image)....
why these strange result?
can anyone help?
thanks
it's one or the other for BF - can't use both- rem one out
Code:
'these if is for be changed
If blnTransparentImage = True Then
Dim BF As Long
Const USE_BITMAP_ALPHA = &H1000000 'AC_SRC_ALPHA scaled up to the 4th byte of a long
BF = 128 * &H10000 'semi transparent ignoring bitmaps alpha channel
'BF = 255 * &H10000 Or USE_BITMAP_ALPHA 'fully opaque using bitmaps alpha channel
picGraphicsEffects.Picture = UserControl.Image
AlphaBlend UserControl.hdc, 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight, picGraphicsEffects.hdc, 0, 0, picGraphicsEffects.ScaleWidth, picGraphicsEffects.ScaleHeight, BF
End If
'the next line is need too... when the shadow is desactivated
UserControl.Picture = UserControl.Image
PicAnimation(0).Tag = ""
Call SubTransparent
RaiseEvent ChangeImage(lngActualSubImage)
it's diferent result, but continue with a problem
can you advice me?
(my objective is showing the image(in UC) Opaque)
thanks
you need to create an alpha channel - have a look at the upload for this thread: http://www.vbforums.com/showthread.php?t=558319
Post #9 - I showed the guy how to use an alpha channel with 2 bmp's. Examples files included.
you need to create an alpha channel - have a look at the upload for this thread: http://www.vbforums.com/showthread.php?t=558319
Post #9 - I showed the guy how to use an alpha channel with 2 bmp's. Examples files included.
i'm so sorry... but i'm confuse...
i have seen your project... but i don't understand how can i combine what you said and your project.... sorry...
what is the term "alpha channel"?
(i'm portuguese)
sorry...
Ok I'll do my best to explain:
Regular 24 bit bitmaps have 3 channels
Red
Green
Blue
Commonly known as RGB
Transparent 32 Bit bitmaps have 4 channels:
Red
Green
Blue
Alpha
The RGBA bitmap has a transparency channnel called alpha which is a black and white (gray scale) bitmap where the dark regions are transparent and the light regions are opaque.
In order to use the Alphablend function you have to load in a picture and an alpha channel and premultiply them together so the colors fade with the alpha channel.
Bit Map:
Alpha Channel:
The method of doing this is in the attached project. It also features a moving background which you stated you wanted to do in a different thread.
Try resizing the form as it runs
Last edited by technorobbo; Mar 5th, 2009 at 11:32 PM.
Ok I'll do my best to explain:
Regular 24 bit bitmaps have 3 channels
Red
Green
Blue
Commonly known as RGB
Transparent 32 Bit bitmaps have 4 channels:
Red
Green
Blue
Alpha
The RGBA bitmap has a transparency channnel called alpha which is a black and white (gray scale) bitmap where the dark regions are transparent and the light regions are opaque.
In order to use the Alphablend function you have to load in a picture and an alpha channel and premultiply them together so the colors fade with the alpha channel.
Bit Map:
Alpha Channel:
The method of doing this is in the attached project. It also features a moving background which you stated you wanted to do in a different thread.
Try resizing the form as it runs
ok.... now i catch what you mean(in back("the fire") of ship)....
but i don't understand how can i do it in my Sprite control(if you want i can put it here)
Since the Windows handles painting the controls DC to the screen you have to Alphablend from the control to the parent, see the control example attached:
Since the Windows handles painting the controls DC to the screen you have to Alphablend from the control to the parent, see the control example attached:
thanks... but i'm so sorry tell you these: but it's possivel put the result in UC(is my objective)... i have the control, but the problem i don't understand how use it... it's very confuse.... LaVolte create it.... i will ask him...
i'm so sorry and thanks very much for help me...
(i'm realy sorry if i'm be rude with you)
hi technorobbo
i have news
by your control i build these:
Code:
If blnTransparentImage = True Then
Dim BF As Long
Const USE_BITMAP_ALPHA = &H1000000 'AC_SRC_ALPHA scaled up to the 4th byte of a long
'BF = 128 * &H10000 'semi transparent ignoring bitmaps alpha channel
BF = 255 * &H10000 Or USE_BITMAP_ALPHA 'fully opaque
AlphaBlend UserControl.hdc, 0, 0, UserControl.ScaleWidth, UserControl.ScaleHeight, UserControl.Parent.hdc, Extender.Left / Screen.TwipsPerPixelX, Extender.Top / Screen.TwipsPerPixelY, UserControl.ScaleWidth, UserControl.ScaleHeight, lBF
End If
instead showed in form, i just showed in UC...
i can see positive results
but i have some problems(bugs) can you help me fix them?
thanks
isn't what i expected... see the image...
-1 color that i don't want... the sprite backcolor;
-his by me, or the image order isn't right(1st must be the parent image then the sprite image)?
thanks
AlphaBlend has to be set to the parent of the control. Like this:
Code:
Private Sub UserControl_Paint()
Dim ar As Boolean
AlphaBlend UserControl.Parent.hdc, ScaleX(UserControl.Extender.Left, vbPixels, vbContainerPosition), _
ScaleY(UserControl.Extender.Top, vbPixels, vbContainerPosition), _
200, 125, Shdc, 0, 0, 200, 125, lBF
End Sub
This is from the example in pot #8. If the AlphaBlend is applied to the UC control instead, Windows will not transfer that alpha when it draws the control.
i have 1 project(i'm still not get right results), that i can use the alphablend() that can draw image and controls too, making an excelent opacy way
what i need is alphablend my control with anothers contols and without 1 color.
can anyone advice me?
i build my own TransparentAlphablend sub, but wihtout results
Code:
'how calculate the alpha values: a*rgb1 + (1-a)rgb2
Public Sub TransparentAlphaBlend(ByRef SrcPictureBox As Control, ByRef DstPictureBox As Control, ByRef Opacy As Integer, ByRef TransparentColor As Long)
Dim x As Long, y As Long
Dim lngNewColor As Long
For x = 0 To DstPictureBox.ScaleWidth - 1
For y = 0 To DstPictureBox.ScaleHeight - 1
If GetPixel(DstPictureBox.hdc, x, y) <> Opacy Then
lngNewColor = Opacy * GetPixel(DstPictureBox.hdc, x, y) + (1 - Opacy) * GetPixel(SrcPictureBox.hdc, x, y)
SetPixel DstPictureBox, x, y, lngNewColor
End If
Next y
Next x
End Sub
(the destination image has the front image, and the source has the back image)
but isn't working
can anyone advice me?
thanks
can i combine trasnparentblt() with alphablend() api function?
Don't think so, you may have to manually process the pixels and then use AlphaBlend:
Option 1: test it, no guarantee it will work. I don't know if TransparentBlt modifies the alpha channel on a destination 32bpp DIB/bitmap.
1. Create offscreen 32bpp DIB section & DC
2. Fill the DIB with all zeros
3. Use TransparentBLT to draw your image to that DC
4. Now use AlphaBlend to draw that DC to your control/object
5. Destroy DC & DIB at some point
Option 2
1. Must use 32bpp DIB
2. For each pixel where the RGB value should be made transparent, set its RGBA value to zero (all 4 bytes of that pixel).
3. Now use AlphaBlend API
4. Destroy DIB at some point
Option 3
Using GDI+ this can be done. Though that does mean adding GDI+ APIs to your project and learning how to load an image into GDI+, along with using GdipSetImageAttributesColorKeys, GdipSetImageAttributesColorMatrix, and several more of the GDI+ APIs.
Last edited by LaVolpe; Jun 14th, 2010 at 10:20 AM.
Insomnia is just a byproduct of, "It can't be done"
Don't think so, you may have to manually process the pixels and then use AlphaBlend:
Option 1: test it, no guarantee it will work. I don't know if TransparentBlt modifies the alpha channel on a destination 32bpp DIB/bitmap.
1. Create offscreen 32bpp DIB section & DC
2. Fill the DIB with all zeros
3. Use TransparentBLT to draw your image to that DC
4. Now use AlphaBlend to draw that DC to your control/object
5. Destroy DC & DIB at some point
Option 2
1. Must use 32bpp DIB
2. For each pixel where the RGB value should be made transparent, set its RGBA value to zero (all 4 bytes of that pixel).
3. Now use AlphaBlend API
4. Destroy DIB at some point
Option 3
Using GDI+ this can be done. Though that does mean adding GDI+ APIs to your project and learning how to load an image into GDI+, along with using GdipSetImageAttributesColorKeys, GdipSetImageAttributesColorMatrix, and several more of the GDI+ APIs.
like you see, i have 1 sub:
Code:
'how calculate the alpha values: a*rgb1 + (1-a)rgb2
Public Sub TransparentAlphaBlend(ByRef SrcPictureBox As Control, ByRef DstPictureBox As Control, ByRef Opacy As Integer, ByRef TransparentColor As Long)
Dim x As Long, y As Long
Dim lngNewColor As Long
For x = 0 To DstPictureBox.ScaleWidth - 1
For y = 0 To DstPictureBox.ScaleHeight - 1
If GetPixel(DstPictureBox.hdc, x, y) <> TransparentColor Then
lngNewColor = Opacy * GetPixel(DstPictureBox.hdc, x, y) + (1 - Opacy) * GetPixel(SrcPictureBox.hdc, x, y)
SetPixel DstPictureBox, x, y, lngNewColor
End If
Next y
Next x
End Sub
(these sub is only for test, then i will convert it to DIB's)
the problem is that i recive negative values. can you advice me?
for resolve that problem i use:
Code:
Public Sub TransparentAlphaBlend(ByRef SrcPictureBox As Control, ByRef DstPictureBox As Control, ByRef Opacy As Integer, ByRef TransparentColor As Long)
Dim X As Long, Y As Long
Dim lngNewColor As Long
Dim BF As BLENDFUNCTION, lBF As Long
With BF
.BlendOp = AC_SRC_OVER
.BlendFlags = 0
.SourceConstantAlpha = Opacy
.AlphaFormat = 0
End With
RtlMoveMemory lBF, BF, 4
For X = 0 To DstPictureBox.ScaleWidth - 1
For Y = 0 To SrcPictureBox.ScaleHeight - 1
If GetPixel(DstPictureBox.hdc, X, Y) <> TransparentColor Then
AlphaBlend SrcPictureBox.hdc, X, Y, 1, 1, DstPictureBox.hdc, X, Y, 1, 1, lBF
'lngNewColor = Opacy * GetPixel(DstPictureBox.hdc, X, Y) + (1 - Opacy) * GetPixel(SrcPictureBox.hdc, X, Y)
''SetPixel DstPictureBox, X, Y, lngNewColor
End If
Next Y
Next X
DstPictureBox.Picture = DstPictureBox.Image
End Sub
Last edited by joaquim; Jun 14th, 2010 at 01:59 PM.
GetPixel returning negative values means error. So either X,Y (must be in pixels not twips) are outside of the picturebox's scalewidth/height and/or the DstPictureBox.hDC is not visible if AutoRedraw=False.
Regarding negative values in your calculation...
1. You cannot use the alphablend formula on the pixel value, it must be used on each of the R, G, & B members.
2. So you have to separate the pixel into R, G, & B components first
3. Your calculation uses a range of 0-1 for opacity; therefore, you need to ensure Opacy is a value between 0 and 1. So....
Code:
Dim dblAlpha As Double, R As Long, G As Long, B As Long
Dim SrcRed As Long, SrcBlue As Long, SrcGreen As Long
Dim DstRed As Long, DstBlue As Long, DstGreen As Long
lNewColor =GetPixel(DstPictureBox.hdc, x, y)
dstRed = lNewColor And &HFF
dstGreen = (lNewColor\&H100&) And &HFF
dstBlue = (lNewColor\&H10000) And &HFF
lNewColor =GetPixel(SrcPictureBox.hdc, x, y)
SrcRed = lNewColor And &HFF
SrcGreen = (lNewColor\&H100&) And &HFF
SrcBlue = (lNewColor\&H10000) And &HFF
' If Opacy is a range between 0 and 255 then
dblAlpha = Opacy/255
' If Opacy is a range between 0 and 100% then
dblAlpha = Opacy/100
' If Opacy is a range between 0 and 1 then
dblAlpha = Opacy
R =(dblAlpha*SrcRed) + (1-dblAlpha)*DstRed
G =(dblAlpha*SrcGreen) + (1-dblAlpha)*DstGreen
B =(dblAlpha*SrcBlue) + (1-dblAlpha)*DstBlue
lNewColor = RGB(R, G, B)
Insomnia is just a byproduct of, "It can't be done"
Option Explicit
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
Private Sub Command1_Click()
TransparentAlphaBlend Picture2, Picture1, Val(Text1.Text), GetPixel(Picture2.hdc, 0, 0)
End Sub
Public Sub TransparentAlphaBlend(ByRef SrcPictureBox As Control, ByRef DstPictureBox As Control, ByRef Opacy As Integer, ByRef TransparentColor As Long)
Dim X As Long, Y As Long
Dim lngsrcColor As Long
Dim lngdstColor As Long
Dim lngNewColor As Long
Dim dblAlpha As Double, R As Long, G As Long, B As Long
Dim SrcRed As Long, SrcBlue As Long, SrcGreen As Long
Dim DstRed As Long, DstBlue As Long, DstGreen As Long
For X = 0 To DstPictureBox.ScaleWidth - 1
For Y = 0 To DstPictureBox.ScaleHeight - 1
lngdstColor = GetPixel(DstPictureBox.hdc, X, Y)
lngsrcColor = GetPixel(SrcPictureBox.hdc, X, Y)
If lngsrcColor <> TransparentColor Then
DstRed = lngdstColor And &HFF
DstGreen = (lngdstColor \ &H100&) And &HFF
DstBlue = (lngdstColor \ &H10000) And &HFF
SrcRed = lngsrcColor And &HFF
SrcGreen = (lngsrcColor \ &H100&) And &HFF
SrcBlue = (lngsrcColor \ &H10000) And &HFF
' If Opacy is a range between 0 and 255 then
'dblAlpha = Opacy / 255
' If Opacy is a range between 0 and 100% then
dblAlpha = Opacy / 100
' If Opacy is a range between 0 and 1 then
'dblAlpha = Opacy
R = (dblAlpha * SrcRed) + (1 - dblAlpha) * DstRed
G = (dblAlpha * SrcGreen) + (1 - dblAlpha) * DstGreen
B = (dblAlpha * SrcBlue) + (1 - dblAlpha) * DstBlue
lngNewColor = RGB(R, G, B)
SetPixel DstPictureBox.hdc, X, Y, lngNewColor
End If
Next Y
Next X
End Sub
its working... thanks
to be more precise... it's better if i put the source and destany dimenstion in heather sub, right?
You can speed it up by removing these lines from inside the loop to outside the loop, before the loop starts:
dblAlpha = Opacy / 100
And: cache value of (1 - dblAlpha) and use it in the R, G, B calculations. Maybe: dblAlphaSrc = Opacy/100: dblAlphaDst = 1-dblAlphaSrc
By making that small change you are doing 4 less math calculations per pixel
Insomnia is just a byproduct of, "It can't be done"
You can speed it up by removing these lines from inside the loop to outside the loop, before the loop starts:
dblAlpha = Opacy / 100
And: cache value of (1 - dblAlpha) and use it in the R, G, B calculations. Maybe: dblAlphaSrc = Opacy/100: dblAlphaDst = 1-dblAlphaSrc
By making that small change you are doing 4 less math calculations per pixel
thanks for that tips(i think is the right word).
let me hask 1 think: for these be a good sub, is better build a more complete head sub(with dimensions)?
(for the error i can do a normal code: on error goto...)
I don't see anything wrong with the way you are doing it, other than it is much slower than using DIBs and doing the calculation directly to/from the DIB bytes. Anyway, calling a subroutine from within the loop will just make it slower still. Maybe I misunderstood.
Insomnia is just a byproduct of, "It can't be done"
I don't see anything wrong with the way you are doing it, other than it is much slower than using DIBs and doing the calculation directly to/from the DIB bytes. Anyway, calling a subroutine from within the loop will just make it slower still. Maybe I misunderstood.
now i need help in these code:
Code:
.....
If Opacy > 0 Then
Set picGraphicsEffects.Picture = Nothing
'print everything that is in usercontrol parent(the container where the UC is), but i don't have sure if i recive the image:(
ImageWithControls UserControl.Parent, picGraphicsEffects
picGraphicsEffects.Picture = picGraphicsEffects.Image
Load PicAnimation(PicAnimation.Count)
'copy that image(by uc size and position) to picanimation
BitBlt PicAnimation(PicAnimation.Count - 1).hDC, 0, 0, UserControl.width, UserControl.Height, picGraphicsEffects.hDC, lngOldPosX, lngOldPosY, vbSrcCopy
Set picGraphicsEffects.Picture = Nothing
picGraphicsEffects.Picture = PicAnimation(PicAnimation.Count - 1).Image
PicAnimation(PicAnimation.Count - 1).Picture = UserControl.Image
'combine the 2 images
TransparentAlphaBlend PicAnimation(PicAnimation.Count - 1), picGraphicsEffects, CLng(m_Opacy), IFF(Transparent = TransparentNone, -1, lngTransparentColor)
Unload PicAnimation(PicAnimation.Count - 1)
UserControl.Picture = picGraphicsEffects.Image
End If
.......
UserControl.width & UserControl.Height are in twips, use scalewidth/scaleheight
See if it was that simple. Otherwise, you will have to be more descriptive, we don't know what the wrong results look like nor do we know what the correct results should look like.
Insomnia is just a byproduct of, "It can't be done"
UserControl.width & UserControl.Height are in twips, use scalewidth/scaleheight
See if it was that simple. Otherwise, you will have to be more descriptive, we don't know what the wrong results look like nor do we know what the correct results should look like.
Using LoadPictureGDI+(from my sig). You can load the image either into a DC/bitmap or into a .Picture object(or variable of type IPictureDisp), and use AlphaBlt to draw it. No pre-multiplying needed(assuming the image is a '32 bit'/'RGBA' TIF of PNG).
I just updated the attachment to do exactly what you want... I think. It's called AlphaTransBlt and it combines TransparentBlt with AlphaBlend!
Using LoadPictureGDI+(from my sig). You can load the image either into a DC/bitmap or into a .Picture object(or variable of type IPictureDisp), and use AlphaBlt to draw it. No pre-multiplying needed(assuming the image is a '32 bit'/'RGBA' TIF of PNG).
I just updated the attachment to do exactly what you want... I think. It's called AlphaTransBlt and it combines TransparentBlt with AlphaBlend!
1st - i need an image(with every controls(for that i use PrintWindows api function)) from parent(uc container);
2nd - my sub is slow, but i will convert it to DIB
but thanks
1st - i need an image(with every controls(for that i use PrintWindows api function)) from parent(uc container);
2nd - my sub is slow, but i will convert it to DIB
but thanks
Image(of Form or Picturebox, for instance) is also an IPictureDisp object.
I really don't see any reason why you'd want to use a DIB. Per-pixel calculations are comparatively slow. Creating the DIB from a bitmap, doing the calculations, and converting back to a bitmap is also a lot of overhead.
Last edited by FireXtol; Jun 15th, 2010 at 05:25 PM.
Image(of Form or Picturebox, for instance) is also an IPictureDisp object.
I really don't see any reason why you'd want to use a DIB. Per-pixel calculations are comparatively slow.
confuse... i don't know IPictureDisp object.
"I really don't see any reason why you'd want to use a DIB. Per-pixel calculations are comparatively slow."
i know, but i'm finish these code, then i will convert it
confuse... i don't know IPictureDisp object.
"I really don't see any reason why you'd want to use a DIB. Per-pixel calculations are comparatively slow."
i know, but i'm finish these code, then i will convert it
Form.Image, Form.Picture, PictureBox.Image, PictureBox.Picture, UserControl.Image, PropertyPage.Image, UserDocument.Image, etc. These are all IPictureDisp objects.
IPictureDisp is a class. Its members include: Handle, Height, hPal, Render(method), Type, and Width.
GDI+ facilitates loading a 32 bpp image file(like PNG) such that AlphaBlend can immediately be used on the resulting dc/bitmap. Meaning you don't need any DIBs, and performance will be much better.
Form.Image, Form.Picture, PictureBox.Image, PictureBox.Picture, UserControl.Image, PropertyPage.Image, UserDocument.Image, etc. These are all IPictureDisp objects.
IPictureDisp is a class. Its members include: Handle, Height, hPal, Render(method), Type, and Width.
GDI+ facilitates loading a 32 bpp image file(like PNG) such that AlphaBlend can immediately be used on the resulting dc/bitmap. Meaning you don't need any DIBs, and performance will be much better.
sorry, can you PM me? do you have MSN?
i need more help for finish 1 thing
.....
If Opacy > 0 Then
Set picGraphicsEffects.Picture = Nothing
'print everything that is in usercontrol parent(the container where the UC is), but i don't have sure if i recive the image:(
ImageWithControls UserControl.Parent, picGraphicsEffects
picGraphicsEffects.Picture = picGraphicsEffects.Image
Load PicAnimation(PicAnimation.Count)
'copy that image(by uc size and position) to picanimation
BitBlt PicAnimation(PicAnimation.Count - 1).hDC, 0, 0, UserControl.width, UserControl.Height, picGraphicsEffects.hDC, lngOldPosX, lngOldPosY, vbSrcCopy
Set picGraphicsEffects.Picture = Nothing
picGraphicsEffects.Picture = PicAnimation(PicAnimation.Count - 1).Image
PicAnimation(PicAnimation.Count - 1).Picture = UserControl.Image
'combine the 2 images
TransparentAlphaBlend PicAnimation(PicAnimation.Count - 1), picGraphicsEffects, CLng(m_Opacy), IFF(Transparent = TransparentNone, -1, lngTransparentColor)
Unload PicAnimation(PicAnimation.Count - 1)
UserControl.Picture = picGraphicsEffects.Image
End If
.......
i don't recive right results
I don't know what ImageWithControls does. Don't know what IFF is, a functional if is IIF.
.Parent will be passing what is likely the Form. (ImageWithControls UserControl.Parent, picGraphicsEffects)
I don't know what ImageWithControls does. Don't know what IFF is, a functional if is IIF.
.Parent will be passing what is likely the Form. (ImageWithControls UserControl.Parent, picGraphicsEffects)
Code:
Public Sub ImageWithControls(ByRef srcPicture As Variant, ByRef dstPicture As Variant)
dstPicture.width = srcPicture.width
dstPicture.Height = srcPicture.Height
dstPicture.AutoRedraw = True
PrintWindow srcPicture.hwnd, dstPicture.hDC, 0
dstPicture.Refresh
End Sub
Code:
'Same people says that VB6(normal, without services packs(the my)) has these function, but i recive errors...
'is why i build these one
'these function is a diferent 'if' statement(is more or less the same, but build in same line;)).
Public Function IFF(Condiction As Boolean, TrueValue As Variant, FalseValue As Variant) As Variant
If Condiction = True Then
IFF = TrueValue
Else
IFF = FalseValue
End If
End Function
Then use Container, and not Parent. The Parent is the form. It's not the Picturebox.
Just try it! Add, for instance, a command button to a picturebox and try the following:
Debug.Print Command1.Parent.hWnd, Command1.Container.hWnd
Debug.Print Form1.hWnd, Picture1.hWnd