下面是我所说的“第2个例子”部分。我按照他的方法去做,总不能成功。下文所涉及到的 alphalogo.bmp 文件可以在以下地址下载: http://www.vbaccelerator.com/home/VB/Code/vbMedia/DIB_Sections/Alpha_DIBSection/VB6_Alpha_DIB_Section_Demonstration.zip“第2个例子”部分: Assuming you have a bitmap in the correct format (alphalogo.bmp in the main download is suitable for this) then the simple way to draw it is as follows. To run this you need to create a PictureBox on the main form with AutoRedraw and AutoSize set True.'api声明部分已略去Private Sub Form_Load() Set Picture1.Picture = LoadPicture(App.Path & "\alphalogo.bmp") End SubPrivate Sub Form_Paint()
' Draw a red background to demonstrate the alpha blend under ' the shadow: Me.Line _ (8 + Picture1.ScaleHeight \ 2, 8 + Picture1.ScaleWidth \ 2) - _ (8 + Picture1.ScaleHeight * 3 \ 2, 8 + Picture1.ScaleWidth * 3 \ 2), _ RGB(255, 0, 0), BF
' Now draw the image using per-pixel alpha values: Dim lBlend As Long Dim bf As BLENDFUNCTION
修改后,aBitmap.bmBitsPixel=32,终于弄好了。但是,alphablend 函数要使用一个 DC。请问我应该怎样把这个 DIB 放到一个 DC 里边呢?
不知为什么,LoadPicture在我的WinXP机子上完全可以。不知同样的代码你那里行不行。 (我用vbaccelerator的那个bmp和我自己做的bmp都行)窗口代码:Option ExplicitPrivate Declare Function AlphaBlend Lib "msimg32" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal nHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal blendFunc As Long) As Long Private Const AC_SRC_OVER = &H0 Private Const AC_SRC_ALPHA = &H1 Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function GetObjectA Lib "gdi32" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Private Type BITMAP '14 bytes bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End TypeDim pix As IPictureDisp, pixdc As Long, pixbmp As BITMAPPrivate Sub Form_Load() Set pix = LoadPicture("alphalogo.bmp") pixdc = CreateCompatibleDC(0&) SelectObject pixdc, pix.Handle GetObjectA pix.Handle, LenB(pixbmp), pixbmp End SubPrivate Sub Form_Paint() AlphaBlend Me.hdc, 0&, 0&, pixbmp.bmWidth, pixbmp.bmHeight, _ pixdc, 0&, 0&, pixbmp.bmWidth, pixbmp.bmHeight, _ MakeBlendFunction(AC_SRC_OVER, 0&, 255&, AC_SRC_ALPHA) End SubPrivate Function MakeBlendFunction(ByVal blendOp As Long, ByVal blendFlags As Long, ByVal SourceConstantAlpha As Long, ByVal alphaFormat As Long) As Long MakeBlendFunction = (blendOp And &HFF&) Or ((blendFlags And &HFF&) * &H100&) Or _ ((SourceConstantAlpha And &HFF&) * &H10000) Or ((alphaFormat And &H7F&) * &H1000000) If alphaFormat And &H80& Then MakeBlendFunction = MakeBlendFunction Or &H80000000 End FunctionPrivate Sub Form_Unload(Cancel As Integer) DeleteDC pixdc End Sub
非常感谢 James0001 同志!尽管他/她的方法在我的机子上还不能完全成功,但他/她教与了我如何把图片放到DC中,这恰恰是我原来不懂的。到此结贴。 ---------------------------------------------------------在 James0001 的机子上用 loadpicture 能行得通,但在我这里却不行,我想这也许是VB的版本问题,我用的的 VB 是 SP6 的。后来,我结合了上边用 LoadImage 读取图片的方法,之后按照 James0001 的方法,CreateCompatibleDC,SelectObject,GetObject,然后再 alphablend,成功了。下边是我的源码:'API声明在此略过 Dim pixdc As Long, hBitmap As Long, aBitmap As BITMAPPrivate Sub form_load() hBitmap = LoadImage(App.hInstance, App.Path + "\alphalogo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE Or LR_DEFAULTSIZE Or LR_CREATEDIBSECTION) pixdc = CreateCompatibleDC(0&) SelectObject pixdc, hBitmap GetObject hBitmap, Len(aBitmap), aBitmap End SubPrivate Sub Form_Paint() AlphaBlendMe.hdc, 0&, 0&, aBitmap.bmWidth, aBitmap.bmHeight, _ pixdc, 0&, 0&, aBitmap.bmWidth, aBitmap.bmHeight, _ MakeBlendFunction(AC_SRC_OVER, 0&, 255&, AC_SRC_ALPHA) End SubPrivate Function MakeBlendFunction(...) As Long '请见上贴 end Function
http://www.vbaccelerator.com/home/VB/Code/vbMedia/DIB_Sections/Alpha_DIBSection/VB6_Alpha_DIB_Section_Demonstration.zip“第2个例子”部分:
Assuming you have a bitmap in the correct format (alphalogo.bmp in the main download is suitable for this) then the simple way to draw it is as follows. To run this you need to create a PictureBox on the main form with AutoRedraw and AutoSize set True.'api声明部分已略去Private Sub Form_Load()
Set Picture1.Picture = LoadPicture(App.Path & "\alphalogo.bmp")
End SubPrivate Sub Form_Paint()
' Draw a red background to demonstrate the alpha blend under
' the shadow:
Me.Line _
(8 + Picture1.ScaleHeight \ 2, 8 + Picture1.ScaleWidth \ 2) - _
(8 + Picture1.ScaleHeight * 3 \ 2, 8 + Picture1.ScaleWidth * 3 \ 2), _
RGB(255, 0, 0), BF
' Now draw the image using per-pixel alpha values:
Dim lBlend As Long
Dim bf As BLENDFUNCTION
bf.BlendOp = AC_SRC_OVER
bf.BlendFlags = 0
bf.SourceConstantAlpha = 255
bf.AlphaFormat = AC_SRC_ALPHA
CopyMemory lBlend, bf, 4
AlphaBlend Me.hDC, 8, 8, _
Picture1.ScaleWidth \ Screen.TwipsPerPixelX, _
Picture1.ScaleHeight \ Screen.TwipsPerPixelY, _
Picture1.hDC, 0, 0, _
Picture1.ScaleWidth \ Screen.TwipsPerPixelX, _
Picture1.ScaleHeight \ Screen.TwipsPerPixelY, _
lBlend
End Sub
BF.SourceConstantAlpha = CurrentGray
RtlMoveMemory lBF, BF, 4
AlphaBlend Me.hdc,0,0,W,H,Picture1.hdc,0,0, Picture1.ScaleWidth,Picture1.ScaleHeight, lBF
从PICTUREBOX上向ME窗体贴图,CurrentGray为透明度,窗体的AUTOREDRAW为FALSE可以立即看到效果,如果为TRUE则需要ME.REFRESH
还有要注意的是就是,只有32位的图像才是带ALPHA通道的,似乎只有PHOTOSHOP才支持,BMP位图是没有ALPHA通道的。
所以,我建议你还是用bf.alphaformat=0,并且在执行的速度上是一样的。
http://youngcat.crcoo.com/a.png所以,我还是希望能有什么办法绕过vb,读取图片,并取得图片的DC。
这样的话我可以在我的机子上帮你测试。
(我用vbaccelerator的那个bmp和我自己做的bmp都行)窗口代码:Option ExplicitPrivate Declare Function AlphaBlend Lib "msimg32" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal nHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal blendFunc As Long) As Long
Private Const AC_SRC_OVER = &H0
Private Const AC_SRC_ALPHA = &H1
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetObjectA Lib "gdi32" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Type BITMAP '14 bytes
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End TypeDim pix As IPictureDisp, pixdc As Long, pixbmp As BITMAPPrivate Sub Form_Load()
Set pix = LoadPicture("alphalogo.bmp")
pixdc = CreateCompatibleDC(0&)
SelectObject pixdc, pix.Handle
GetObjectA pix.Handle, LenB(pixbmp), pixbmp
End SubPrivate Sub Form_Paint()
AlphaBlend Me.hdc, 0&, 0&, pixbmp.bmWidth, pixbmp.bmHeight, _
pixdc, 0&, 0&, pixbmp.bmWidth, pixbmp.bmHeight, _
MakeBlendFunction(AC_SRC_OVER, 0&, 255&, AC_SRC_ALPHA)
End SubPrivate Function MakeBlendFunction(ByVal blendOp As Long, ByVal blendFlags As Long, ByVal SourceConstantAlpha As Long, ByVal alphaFormat As Long) As Long
MakeBlendFunction = (blendOp And &HFF&) Or ((blendFlags And &HFF&) * &H100&) Or _
((SourceConstantAlpha And &HFF&) * &H10000) Or ((alphaFormat And &H7F&) * &H1000000)
If alphaFormat And &H80& Then MakeBlendFunction = MakeBlendFunction Or &H80000000
End FunctionPrivate Sub Form_Unload(Cancel As Integer)
DeleteDC pixdc
End Sub
---------------------------------------------------------在 James0001 的机子上用 loadpicture 能行得通,但在我这里却不行,我想这也许是VB的版本问题,我用的的 VB 是 SP6 的。后来,我结合了上边用 LoadImage 读取图片的方法,之后按照 James0001 的方法,CreateCompatibleDC,SelectObject,GetObject,然后再 alphablend,成功了。下边是我的源码:'API声明在此略过
Dim pixdc As Long, hBitmap As Long, aBitmap As BITMAPPrivate Sub form_load()
hBitmap = LoadImage(App.hInstance, App.Path + "\alphalogo.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE Or LR_DEFAULTSIZE Or LR_CREATEDIBSECTION)
pixdc = CreateCompatibleDC(0&)
SelectObject pixdc, hBitmap
GetObject hBitmap, Len(aBitmap), aBitmap
End SubPrivate Sub Form_Paint()
AlphaBlendMe.hdc, 0&, 0&, aBitmap.bmWidth, aBitmap.bmHeight, _
pixdc, 0&, 0&, aBitmap.bmWidth, aBitmap.bmHeight, _
MakeBlendFunction(AC_SRC_OVER, 0&, 255&, AC_SRC_ALPHA)
End SubPrivate Function MakeBlendFunction(...) As Long
'请见上贴
end Function