下面的代码希望对你有用Option Explicit'------------------ Structure ------------------------------------------------ Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End TypeType myColor24 B As Byte G As Byte R As Byte End TypeType myColor32 B As Byte G As Byte R As Byte A As Byte End Type '------------------ API ------------------------------------------------------ Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Declare Function GetObjectAPI& Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) '----------------- Global Function ------------------------------------------- '功能:将前景位图经掩模运算后与背景混合,然后按整体透明度复制到目的位图。 '引用:(Type)BITMAP,(Type)myColor24,(API)GetBitmapBits,(API)SetBitmapBits,(API)GetObjectAPI '说明:如果未指定hFSourceBmp(前景),掩模将失去作用;如果未指定hMaskBmp(掩模),前景将完全覆盖背景;如果未指定AlphaRate(透明度),将不做整体透明处理 '参数: ' hDestBmp 目的位图句柄 ' DX 目的X坐标 ' DY 目的Y坐标 ' DW 目的宽度 ' DH 目的高度 ' hBSourceBmp 背景位图句柄 ' BSX 背景X坐标 ' BSY 背景Y坐标 ' hFSourceBmp 前景位图句柄 ' FSX 前景X坐标 ' FSY 前景Y坐标 ' hMaskBmp 掩模位图句柄 ' MX 掩模X坐标 ' MY 掩模Y坐标 ' Alpha 整体透明度 Sub ABImage(ByVal hDest As Long, ByVal DX As Long, ByVal DY As Long, ByVal DW As Long, ByVal DH As Long, ByVal hBSource As Long, ByVal BSX As Long, ByVal BSY As Long, ByVal hFSource As Long, ByVal FSX As Long, ByVal FSY As Long, ByVal hMask As Long, ByVal MX As Long, ByVal MY As Long, ByVal AlphaRate As Byte)
'各位图的信息 Dim DInfo As BITMAP, BSInfo As BITMAP, FSInfo As BITMAP, MInfo As BITMAP '各位图的数据 Dim DData() As myColor24, BSData() As myColor24, FSData() As myColor24, MData() As myColor24 Dim DData32() As myColor32, BSData32() As myColor32, FSData32() As myColor32, MData32() As myColor32 'X,Y=循环变量;W,H=循环次数;OffsetX,OffsetY=相对于目的位图坐标偏移 Dim X As Long, Y As Long, W As Long, H As Long, OffsetX As Long, OffsetY As Long '混合比率 Dim Rate As Single
'得到各位图的信息 If GetObjectAPI(hDest, Len(DInfo), DInfo) = 0 Then Exit Sub If GetObjectAPI(hBSource, Len(BSInfo), BSInfo) = 0 Then Exit Sub If GetObjectAPI(hFSource, Len(FSInfo), FSInfo) = 0 Then Exit Sub If GetObjectAPI(hMask, Len(MInfo), MInfo) = 0 Then Exit Sub
'确定循环次数及偏移 OffsetX = IIf(DX > 0, DX, 0) OffsetY = IIf(DY > 0, DY, 0) If OffsetX >= DInfo.bmWidth Or OffsetY >= DInfo.bmHeight Then Exit Sub If BSX > BSInfo.bmWidth Or BSY > BSInfo.bmHeight Or FSX > FSInfo.bmWidth Or FSY > FSInfo.bmHeight Or MX > MInfo.bmWidth Or MY > MInfo.bmHeight Then Exit Sub '保证范围有效 W = IIf(DX >= 0, DW, DW + DX) W = IIf(OffsetX + W > DInfo.bmWidth, DInfo.bmWidth - OffsetX, W) W = IIf(BSInfo.bmWidth - BSX > W, W, BSInfo.bmWidth - BSX) W = IIf(FSInfo.bmWidth - FSX > W, W, FSInfo.bmWidth - FSX) W = IIf(MInfo.bmWidth - MX > W, W, MInfo.bmWidth - MX) H = IIf(DY >= 0, DH, DH + DY) H = IIf(OffsetY + H > DInfo.bmHeight, DInfo.bmHeight - OffsetY, H) H = IIf(BSInfo.bmHeight - BSY > H, H, BSInfo.bmHeight - BSY) H = IIf(FSInfo.bmHeight - FSY > H, H, FSInfo.bmHeight - FSY) H = IIf(MInfo.bmHeight - MY > H, H, MInfo.bmHeight - MY) If W <= 0 Or H <= 0 Then Exit Sub '保证范围有效
'如果为24位位图 If DInfo.bmBitsPixel = 24 And BSInfo.bmBitsPixel = 24 And FSInfo.bmBitsPixel = 24 And MInfo.bmBitsPixel = 24 Then '得到各位图数据 ReDim DData(0) As myColor24, BSData(0) As myColor24, FSData(0) As myColor24, MData(0) As myColor24 ReDim DData(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor24 GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0) ReDim BSData(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor24 GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 3, BSData(0, 0) ReDim FSData(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor24 GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 3, FSData(0, 0) ReDim MData(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor24 GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 3, MData(0, 0) '处理数据 For Y = 0 To H - 1 For X = 0 To W - 1 Rate = (CLng(MData(X + MX, Y + MY).R) + MData(X + MX, Y + MY).G + MData(X + MX, Y + MY).B) / 765 '\3/255 灰度化掩模 DData(X + DX, Y + DY).R = FSData(X + FSX, Y + FSY).R + (CLng(BSData(X + BSX, Y + BSY).R) - FSData(X + FSX, Y + FSY).R) * Rate 'Alpha混合 DData(X + DX, Y + DY).G = FSData(X + FSX, Y + FSY).G + (CLng(BSData(X + BSX, Y + BSY).G) - FSData(X + FSX, Y + FSY).G) * Rate 'Alpha混合 DData(X + DX, Y + DY).B = FSData(X + FSX, Y + FSY).B + (CLng(BSData(X + BSX, Y + BSY).B) - FSData(X + FSX, Y + FSY).B) * Rate 'Alpha混合 Next X Next Y '返回数据 SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0) Erase DData, BSData, FSData, MData
'如果为32位位图 ElseIf DInfo.bmBitsPixel = 32 And BSInfo.bmBitsPixel = 32 And FSInfo.bmBitsPixel = 32 And MInfo.bmBitsPixel = 32 Then '得到各位图数据 ReDim DData32(0) As myColor32, BSData32(0) As myColor32, FSData32(0) As myColor32, MData32(0) As myColor32 ReDim DData32(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor32 GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0) ReDim BSData32(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor32 GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 4, BSData32(0, 0) ReDim FSData32(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor32 GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 4, FSData32(0, 0) ReDim MData32(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor32 GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 4, MData32(0, 0) '处理数据 For Y = 0 To H - 1 For X = 0 To W - 1 Rate = ((255 - CLng(MData32(X + MX, Y + MY).R)) + (255 - CLng(MData32(X + MX, Y + MY).G)) + (255 - CLng(MData32(X + MX, Y + MY).B))) / 765 '\3/255 灰度化掩模 DData32(X + DX, Y + DY).R = FSData32(X + FSX, Y + FSY).R + (CLng(BSData32(X + BSX, Y + BSY).R) - FSData32(X + FSX, Y + FSY).R) * Rate 'Alpha混合 DData32(X + DX, Y + DY).G = FSData32(X + FSX, Y + FSY).G + (CLng(BSData32(X + BSX, Y + BSY).G) - FSData32(X + FSX, Y + FSY).G) * Rate 'Alpha混合 DData32(X + DX, Y + DY).B = FSData32(X + FSX, Y + FSY).B + (CLng(BSData32(X + BSX, Y + BSY).B) - FSData32(X + FSX, Y + FSY).B) * Rate 'Alpha混合 Next X Next Y '返回数据 SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0) Erase DData32, BSData32, FSData32, MData32 End If
End Sub
上面的代码有些问题,更新如下: '------------------ Structure ------------------------------------------------ Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End TypeType myColor24 B As Byte G As Byte R As Byte End TypeType myColor32 B As Byte G As Byte R As Byte A As Byte End Type '------------------ API ------------------------------------------------------ Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Declare Function GetObjectAPI& Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) '----------------- Global Function ------------------------------------------- '功能:将前景位图经掩模运算后与背景混合,然后按整体透明度复制到目的位图。 '引用:(Type)BITMAP,(Type)myColor24,(API)GetBitmapBits,(API)SetBitmapBits,(API)GetObjectAPI '参数: ' hDestBmp 目的位图句柄 ' DX 目的X坐标 ' DY 目的Y坐标 ' DW 目的宽度 ' DH 目的高度 ' hBSourceBmp 背景位图句柄 ' BX 背景X坐标 ' BY 背景Y坐标 ' hFSourceBmp 前景位图句柄 ' FX 前景X坐标 ' FY 前景Y坐标 ' hMaskBmp 掩模位图句柄(可选) ' MX 掩模X坐标(可选) ' MY 掩模Y坐标(可选) ' Transparency 整体透明度(可选)
Sub ABImage(ByVal hDest As Long, ByVal DX As Long, ByVal DY As Long, ByVal DW As Long, ByVal DH As Long, ByVal hBSource As Long, ByVal BX As Long, ByVal BY As Long, ByVal hFSource As Long, ByVal FX As Long, ByVal FY As Long, Optional ByVal hMask As Long = 0, Optional ByVal MX As Long = 0, Optional ByVal MY As Long = 0, Optional ByVal Transparency As Byte = 0)
'各位图的信息 Dim DInfo As BITMAP, BSInfo As BITMAP, FSInfo As BITMAP, MInfo As BITMAP '各位图的数据 Dim DData() As myColor24, BSData() As myColor24, FSData() As myColor24, MData() As myColor24 Dim DData32() As myColor32, BSData32() As myColor32, FSData32() As myColor32, MData32() As myColor32 'X,Y=循环变量;W,H=循环次数;OffsetX,OffsetY=相对于目的位图坐标偏移 Dim X As Long, Y As Long, W As Long, H As Long, OffsetX As Long, OffsetY As Long '掩模混合比率, 整体混合比率, 临时数据 Dim MaskRate As Single, AlphaRate As Single, Temp As Byte AlphaRate = CSng(Transparency) / 255
'得到各位图的信息 If GetObjectAPI(hDest, Len(DInfo), DInfo) = 0 Then Exit Sub If GetObjectAPI(hBSource, Len(BSInfo), BSInfo) = 0 Then Exit Sub If GetObjectAPI(hFSource, Len(FSInfo), FSInfo) = 0 Then Exit Sub If GetObjectAPI(hMask, Len(MInfo), MInfo) = 0 Then hMask = 0
'确定循环次数及偏移 OffsetX = IIf(DX > 0, DX, 0) OffsetY = IIf(DY > 0, DY, 0) If OffsetX >= DInfo.bmWidth Or OffsetY >= DInfo.bmHeight Then Exit Sub If BX > BSInfo.bmWidth Or BY > BSInfo.bmHeight Or FX > FSInfo.bmWidth Or FY > FSInfo.bmHeight Or MX > MInfo.bmWidth Or MY > MInfo.bmHeight Then Exit Sub '保证范围有效 W = IIf(DX >= 0, DW, DW + DX) W = IIf(OffsetX + W > DInfo.bmWidth, DInfo.bmWidth - OffsetX, W) W = IIf(BSInfo.bmWidth - BX > W, W, BSInfo.bmWidth - BX) W = IIf(FSInfo.bmWidth - FX > W, W, FSInfo.bmWidth - FX) If hMask > 0 Then W = IIf(MInfo.bmWidth - MX > W, W, MInfo.bmWidth - MX) H = IIf(DY >= 0, DH, DH + DY) H = IIf(OffsetY + H > DInfo.bmHeight, DInfo.bmHeight - OffsetY, H) H = IIf(BSInfo.bmHeight - BY > H, H, BSInfo.bmHeight - BY) H = IIf(FSInfo.bmHeight - FY > H, H, FSInfo.bmHeight - FY) If hMask > 0 Then H = IIf(MInfo.bmHeight - MY > H, H, MInfo.bmHeight - MY) If W <= 0 Or H <= 0 Then Exit Sub '保证范围有效
'如果为24位位图 If DInfo.bmBitsPixel = 24 And BSInfo.bmBitsPixel = 24 And FSInfo.bmBitsPixel = 24 And IIf(hMask <> 0, MInfo.bmBitsPixel = 24, True) Then '得到各位图数据 ReDim DData(0) As myColor24, BSData(0) As myColor24, FSData(0) As myColor24, MData(0) As myColor24 ReDim DData(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor24 GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0) ReDim BSData(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor24 GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 3, BSData(0, 0) ReDim FSData(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor24 GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 3, FSData(0, 0) If hMask <> 0 Then ReDim MData(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor24 GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 3, MData(0, 0) End If '处理数据 For Y = 0 To H - 1 For X = 0 To W - 1 If hMask <> 0 Then MaskRate = CSng(MData(X + MX, Y + MY).R + MData(X + MX, Y + MY).G + MData(X + MX, Y + MY).B) / 765 '\3/255 灰度化掩模 Else MaskRate = 0 End If '计算目标红 Temp = FSData(X + FX, Y + FY).R + (CLng(BSData(X + BX, Y + BY).R) - FSData(X + FX, Y + FY).R) * MaskRate DData(X + DX, Y + DY).R = Temp + (CLng(BSData(X + BX, Y + BY).R) - Temp) * AlphaRate '计算目标绿 Temp = FSData(X + FX, Y + FY).G + (CLng(BSData(X + BX, Y + BY).G) - FSData(X + FX, Y + FY).G) * MaskRate DData(X + DX, Y + DY).G = Temp + (CLng(BSData(X + BX, Y + BY).G) - Temp) * AlphaRate '计算目标蓝 Temp = FSData(X + FX, Y + FY).B + (CLng(BSData(X + BX, Y + BY).B) - FSData(X + FX, Y + FY).B) * MaskRate DData(X + DX, Y + DY).B = Temp + (CLng(BSData(X + BX, Y + BY).B) - Temp) * AlphaRate Next X Next Y '返回数据 SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0) Erase DData, BSData, FSData, MData
'如果为32位位图 ElseIf DInfo.bmBitsPixel = 32 And BSInfo.bmBitsPixel = 32 And FSInfo.bmBitsPixel = 32 And IIf(hMask <> 0, MInfo.bmBitsPixel = 32, True) Then '得到各位图数据 ReDim DData32(0) As myColor32, BSData32(0) As myColor32, FSData32(0) As myColor32, MData32(0) As myColor32 ReDim DData32(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor32 GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0) ReDim BSData32(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor32 GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 4, BSData32(0, 0) ReDim FSData32(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor32 GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 4, FSData32(0, 0) If hMask <> 0 Then ReDim MData32(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor32 GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 4, MData32(0, 0) End If '处理数据 For Y = 0 To H - 1 For X = 0 To W - 1 '灰度化掩模 If hMask <> 0 Then MaskRate = CSng((255 - MData32(X + MX, Y + MY).R) + (255 - MData32(X + MX, Y + MY).G) + (255 - MData32(X + MX, Y + MY).B)) / 765 '\3/255 Else MaskRate = 0 End If '计算目标红 Temp = FSData32(X + FX, Y + FY).R + (CLng(BSData32(X + BX, Y + BY).R) - FSData32(X + FX, Y + FY).R) * MaskRate DData32(X + DX, Y + DY).R = Temp + (CLng(BSData32(X + BX, Y + BY).R) - Temp) * AlphaRate '计算目标绿 Temp = FSData32(X + FX, Y + FY).G + (CLng(BSData32(X + BX, Y + BY).G) - FSData32(X + FX, Y + FY).G) * MaskRate DData32(X + DX, Y + DY).G = Temp + (CLng(BSData32(X + BX, Y + BY).G) - Temp) * AlphaRate '计算目标蓝 Temp = FSData32(X + FX, Y + FY).B + (CLng(BSData32(X + BX, Y + BY).B) - FSData32(X + FX, Y + FY).B) * MaskRate DData32(X + DX, Y + DY).B = Temp + (CLng(BSData32(X + BX, Y + BY).B) - Temp) * AlphaRate Next X Next Y '返回数据 SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0) Erase DData32, BSData32, FSData32, MData32 End If
Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End TypeType myColor24
B As Byte
G As Byte
R As Byte
End TypeType myColor32
B As Byte
G As Byte
R As Byte
A As Byte
End Type
'------------------ API ------------------------------------------------------
Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Declare Function GetObjectAPI& Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any)
'----------------- Global Function -------------------------------------------
'功能:将前景位图经掩模运算后与背景混合,然后按整体透明度复制到目的位图。
'引用:(Type)BITMAP,(Type)myColor24,(API)GetBitmapBits,(API)SetBitmapBits,(API)GetObjectAPI
'说明:如果未指定hFSourceBmp(前景),掩模将失去作用;如果未指定hMaskBmp(掩模),前景将完全覆盖背景;如果未指定AlphaRate(透明度),将不做整体透明处理
'参数:
' hDestBmp 目的位图句柄
' DX 目的X坐标
' DY 目的Y坐标
' DW 目的宽度
' DH 目的高度
' hBSourceBmp 背景位图句柄
' BSX 背景X坐标
' BSY 背景Y坐标
' hFSourceBmp 前景位图句柄
' FSX 前景X坐标
' FSY 前景Y坐标
' hMaskBmp 掩模位图句柄
' MX 掩模X坐标
' MY 掩模Y坐标
' Alpha 整体透明度
Sub ABImage(ByVal hDest As Long, ByVal DX As Long, ByVal DY As Long, ByVal DW As Long, ByVal DH As Long, ByVal hBSource As Long, ByVal BSX As Long, ByVal BSY As Long, ByVal hFSource As Long, ByVal FSX As Long, ByVal FSY As Long, ByVal hMask As Long, ByVal MX As Long, ByVal MY As Long, ByVal AlphaRate As Byte)
'各位图的信息
Dim DInfo As BITMAP, BSInfo As BITMAP, FSInfo As BITMAP, MInfo As BITMAP
'各位图的数据
Dim DData() As myColor24, BSData() As myColor24, FSData() As myColor24, MData() As myColor24
Dim DData32() As myColor32, BSData32() As myColor32, FSData32() As myColor32, MData32() As myColor32
'X,Y=循环变量;W,H=循环次数;OffsetX,OffsetY=相对于目的位图坐标偏移
Dim X As Long, Y As Long, W As Long, H As Long, OffsetX As Long, OffsetY As Long
'混合比率
Dim Rate As Single
'得到各位图的信息
If GetObjectAPI(hDest, Len(DInfo), DInfo) = 0 Then Exit Sub
If GetObjectAPI(hBSource, Len(BSInfo), BSInfo) = 0 Then Exit Sub
If GetObjectAPI(hFSource, Len(FSInfo), FSInfo) = 0 Then Exit Sub
If GetObjectAPI(hMask, Len(MInfo), MInfo) = 0 Then Exit Sub
'确定循环次数及偏移
OffsetX = IIf(DX > 0, DX, 0)
OffsetY = IIf(DY > 0, DY, 0)
If OffsetX >= DInfo.bmWidth Or OffsetY >= DInfo.bmHeight Then Exit Sub
If BSX > BSInfo.bmWidth Or BSY > BSInfo.bmHeight Or FSX > FSInfo.bmWidth Or FSY > FSInfo.bmHeight Or MX > MInfo.bmWidth Or MY > MInfo.bmHeight Then Exit Sub '保证范围有效
W = IIf(DX >= 0, DW, DW + DX)
W = IIf(OffsetX + W > DInfo.bmWidth, DInfo.bmWidth - OffsetX, W)
W = IIf(BSInfo.bmWidth - BSX > W, W, BSInfo.bmWidth - BSX)
W = IIf(FSInfo.bmWidth - FSX > W, W, FSInfo.bmWidth - FSX)
W = IIf(MInfo.bmWidth - MX > W, W, MInfo.bmWidth - MX)
H = IIf(DY >= 0, DH, DH + DY)
H = IIf(OffsetY + H > DInfo.bmHeight, DInfo.bmHeight - OffsetY, H)
H = IIf(BSInfo.bmHeight - BSY > H, H, BSInfo.bmHeight - BSY)
H = IIf(FSInfo.bmHeight - FSY > H, H, FSInfo.bmHeight - FSY)
H = IIf(MInfo.bmHeight - MY > H, H, MInfo.bmHeight - MY)
If W <= 0 Or H <= 0 Then Exit Sub '保证范围有效
'如果为24位位图
If DInfo.bmBitsPixel = 24 And BSInfo.bmBitsPixel = 24 And FSInfo.bmBitsPixel = 24 And MInfo.bmBitsPixel = 24 Then
'得到各位图数据
ReDim DData(0) As myColor24, BSData(0) As myColor24, FSData(0) As myColor24, MData(0) As myColor24
ReDim DData(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor24
GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0)
ReDim BSData(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor24
GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 3, BSData(0, 0)
ReDim FSData(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor24
GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 3, FSData(0, 0)
ReDim MData(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor24
GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 3, MData(0, 0)
'处理数据
For Y = 0 To H - 1
For X = 0 To W - 1
Rate = (CLng(MData(X + MX, Y + MY).R) + MData(X + MX, Y + MY).G + MData(X + MX, Y + MY).B) / 765 '\3/255 灰度化掩模
DData(X + DX, Y + DY).R = FSData(X + FSX, Y + FSY).R + (CLng(BSData(X + BSX, Y + BSY).R) - FSData(X + FSX, Y + FSY).R) * Rate 'Alpha混合
DData(X + DX, Y + DY).G = FSData(X + FSX, Y + FSY).G + (CLng(BSData(X + BSX, Y + BSY).G) - FSData(X + FSX, Y + FSY).G) * Rate 'Alpha混合
DData(X + DX, Y + DY).B = FSData(X + FSX, Y + FSY).B + (CLng(BSData(X + BSX, Y + BSY).B) - FSData(X + FSX, Y + FSY).B) * Rate 'Alpha混合
Next X
Next Y
'返回数据
SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0)
Erase DData, BSData, FSData, MData
'如果为32位位图
ElseIf DInfo.bmBitsPixel = 32 And BSInfo.bmBitsPixel = 32 And FSInfo.bmBitsPixel = 32 And MInfo.bmBitsPixel = 32 Then
'得到各位图数据
ReDim DData32(0) As myColor32, BSData32(0) As myColor32, FSData32(0) As myColor32, MData32(0) As myColor32
ReDim DData32(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor32
GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0)
ReDim BSData32(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor32
GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 4, BSData32(0, 0)
ReDim FSData32(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor32
GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 4, FSData32(0, 0)
ReDim MData32(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor32
GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 4, MData32(0, 0)
'处理数据
For Y = 0 To H - 1
For X = 0 To W - 1
Rate = ((255 - CLng(MData32(X + MX, Y + MY).R)) + (255 - CLng(MData32(X + MX, Y + MY).G)) + (255 - CLng(MData32(X + MX, Y + MY).B))) / 765 '\3/255 灰度化掩模
DData32(X + DX, Y + DY).R = FSData32(X + FSX, Y + FSY).R + (CLng(BSData32(X + BSX, Y + BSY).R) - FSData32(X + FSX, Y + FSY).R) * Rate 'Alpha混合
DData32(X + DX, Y + DY).G = FSData32(X + FSX, Y + FSY).G + (CLng(BSData32(X + BSX, Y + BSY).G) - FSData32(X + FSX, Y + FSY).G) * Rate 'Alpha混合
DData32(X + DX, Y + DY).B = FSData32(X + FSX, Y + FSY).B + (CLng(BSData32(X + BSX, Y + BSY).B) - FSData32(X + FSX, Y + FSY).B) * Rate 'Alpha混合
Next X
Next Y
'返回数据
SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0)
Erase DData32, BSData32, FSData32, MData32
End If
End Sub
'------------------ Structure ------------------------------------------------
Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End TypeType myColor24
B As Byte
G As Byte
R As Byte
End TypeType myColor32
B As Byte
G As Byte
R As Byte
A As Byte
End Type
'------------------ API ------------------------------------------------------
Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Declare Function GetObjectAPI& Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any)
'----------------- Global Function -------------------------------------------
'功能:将前景位图经掩模运算后与背景混合,然后按整体透明度复制到目的位图。
'引用:(Type)BITMAP,(Type)myColor24,(API)GetBitmapBits,(API)SetBitmapBits,(API)GetObjectAPI
'参数:
' hDestBmp 目的位图句柄
' DX 目的X坐标
' DY 目的Y坐标
' DW 目的宽度
' DH 目的高度
' hBSourceBmp 背景位图句柄
' BX 背景X坐标
' BY 背景Y坐标
' hFSourceBmp 前景位图句柄
' FX 前景X坐标
' FY 前景Y坐标
' hMaskBmp 掩模位图句柄(可选)
' MX 掩模X坐标(可选)
' MY 掩模Y坐标(可选)
' Transparency 整体透明度(可选)
Sub ABImage(ByVal hDest As Long, ByVal DX As Long, ByVal DY As Long, ByVal DW As Long, ByVal DH As Long, ByVal hBSource As Long, ByVal BX As Long, ByVal BY As Long, ByVal hFSource As Long, ByVal FX As Long, ByVal FY As Long, Optional ByVal hMask As Long = 0, Optional ByVal MX As Long = 0, Optional ByVal MY As Long = 0, Optional ByVal Transparency As Byte = 0)
'各位图的信息
Dim DInfo As BITMAP, BSInfo As BITMAP, FSInfo As BITMAP, MInfo As BITMAP
'各位图的数据
Dim DData() As myColor24, BSData() As myColor24, FSData() As myColor24, MData() As myColor24
Dim DData32() As myColor32, BSData32() As myColor32, FSData32() As myColor32, MData32() As myColor32
'X,Y=循环变量;W,H=循环次数;OffsetX,OffsetY=相对于目的位图坐标偏移
Dim X As Long, Y As Long, W As Long, H As Long, OffsetX As Long, OffsetY As Long
'掩模混合比率, 整体混合比率, 临时数据
Dim MaskRate As Single, AlphaRate As Single, Temp As Byte
AlphaRate = CSng(Transparency) / 255
'得到各位图的信息
If GetObjectAPI(hDest, Len(DInfo), DInfo) = 0 Then Exit Sub
If GetObjectAPI(hBSource, Len(BSInfo), BSInfo) = 0 Then Exit Sub
If GetObjectAPI(hFSource, Len(FSInfo), FSInfo) = 0 Then Exit Sub
If GetObjectAPI(hMask, Len(MInfo), MInfo) = 0 Then hMask = 0
'确定循环次数及偏移
OffsetX = IIf(DX > 0, DX, 0)
OffsetY = IIf(DY > 0, DY, 0)
If OffsetX >= DInfo.bmWidth Or OffsetY >= DInfo.bmHeight Then Exit Sub
If BX > BSInfo.bmWidth Or BY > BSInfo.bmHeight Or FX > FSInfo.bmWidth Or FY > FSInfo.bmHeight Or MX > MInfo.bmWidth Or MY > MInfo.bmHeight Then Exit Sub '保证范围有效
W = IIf(DX >= 0, DW, DW + DX)
W = IIf(OffsetX + W > DInfo.bmWidth, DInfo.bmWidth - OffsetX, W)
W = IIf(BSInfo.bmWidth - BX > W, W, BSInfo.bmWidth - BX)
W = IIf(FSInfo.bmWidth - FX > W, W, FSInfo.bmWidth - FX)
If hMask > 0 Then W = IIf(MInfo.bmWidth - MX > W, W, MInfo.bmWidth - MX)
H = IIf(DY >= 0, DH, DH + DY)
H = IIf(OffsetY + H > DInfo.bmHeight, DInfo.bmHeight - OffsetY, H)
H = IIf(BSInfo.bmHeight - BY > H, H, BSInfo.bmHeight - BY)
H = IIf(FSInfo.bmHeight - FY > H, H, FSInfo.bmHeight - FY)
If hMask > 0 Then H = IIf(MInfo.bmHeight - MY > H, H, MInfo.bmHeight - MY)
If W <= 0 Or H <= 0 Then Exit Sub '保证范围有效
'如果为24位位图
If DInfo.bmBitsPixel = 24 And BSInfo.bmBitsPixel = 24 And FSInfo.bmBitsPixel = 24 And IIf(hMask <> 0, MInfo.bmBitsPixel = 24, True) Then
'得到各位图数据
ReDim DData(0) As myColor24, BSData(0) As myColor24, FSData(0) As myColor24, MData(0) As myColor24
ReDim DData(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor24
GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0)
ReDim BSData(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor24
GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 3, BSData(0, 0)
ReDim FSData(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor24
GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 3, FSData(0, 0)
If hMask <> 0 Then
ReDim MData(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor24
GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 3, MData(0, 0)
End If
'处理数据
For Y = 0 To H - 1
For X = 0 To W - 1
If hMask <> 0 Then
MaskRate = CSng(MData(X + MX, Y + MY).R + MData(X + MX, Y + MY).G + MData(X + MX, Y + MY).B) / 765 '\3/255 灰度化掩模
Else
MaskRate = 0
End If
'计算目标红
Temp = FSData(X + FX, Y + FY).R + (CLng(BSData(X + BX, Y + BY).R) - FSData(X + FX, Y + FY).R) * MaskRate
DData(X + DX, Y + DY).R = Temp + (CLng(BSData(X + BX, Y + BY).R) - Temp) * AlphaRate
'计算目标绿
Temp = FSData(X + FX, Y + FY).G + (CLng(BSData(X + BX, Y + BY).G) - FSData(X + FX, Y + FY).G) * MaskRate
DData(X + DX, Y + DY).G = Temp + (CLng(BSData(X + BX, Y + BY).G) - Temp) * AlphaRate
'计算目标蓝
Temp = FSData(X + FX, Y + FY).B + (CLng(BSData(X + BX, Y + BY).B) - FSData(X + FX, Y + FY).B) * MaskRate
DData(X + DX, Y + DY).B = Temp + (CLng(BSData(X + BX, Y + BY).B) - Temp) * AlphaRate
Next X
Next Y
'返回数据
SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 3, DData(0, 0)
Erase DData, BSData, FSData, MData
'如果为32位位图
ElseIf DInfo.bmBitsPixel = 32 And BSInfo.bmBitsPixel = 32 And FSInfo.bmBitsPixel = 32 And IIf(hMask <> 0, MInfo.bmBitsPixel = 32, True) Then
'得到各位图数据
ReDim DData32(0) As myColor32, BSData32(0) As myColor32, FSData32(0) As myColor32, MData32(0) As myColor32
ReDim DData32(DInfo.bmWidth - 1, DInfo.bmHeight - 1) As myColor32
GetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0)
ReDim BSData32(BSInfo.bmWidth - 1, BSInfo.bmHeight - 1) As myColor32
GetBitmapBits hBSource, BSInfo.bmWidth * BSInfo.bmHeight * 4, BSData32(0, 0)
ReDim FSData32(FSInfo.bmWidth - 1, FSInfo.bmHeight - 1) As myColor32
GetBitmapBits hFSource, FSInfo.bmWidth * FSInfo.bmHeight * 4, FSData32(0, 0)
If hMask <> 0 Then
ReDim MData32(MInfo.bmWidth - 1, MInfo.bmHeight - 1) As myColor32
GetBitmapBits hMask, MInfo.bmWidth * MInfo.bmHeight * 4, MData32(0, 0)
End If
'处理数据
For Y = 0 To H - 1
For X = 0 To W - 1
'灰度化掩模
If hMask <> 0 Then
MaskRate = CSng((255 - MData32(X + MX, Y + MY).R) + (255 - MData32(X + MX, Y + MY).G) + (255 - MData32(X + MX, Y + MY).B)) / 765 '\3/255
Else
MaskRate = 0
End If
'计算目标红
Temp = FSData32(X + FX, Y + FY).R + (CLng(BSData32(X + BX, Y + BY).R) - FSData32(X + FX, Y + FY).R) * MaskRate
DData32(X + DX, Y + DY).R = Temp + (CLng(BSData32(X + BX, Y + BY).R) - Temp) * AlphaRate
'计算目标绿
Temp = FSData32(X + FX, Y + FY).G + (CLng(BSData32(X + BX, Y + BY).G) - FSData32(X + FX, Y + FY).G) * MaskRate
DData32(X + DX, Y + DY).G = Temp + (CLng(BSData32(X + BX, Y + BY).G) - Temp) * AlphaRate
'计算目标蓝
Temp = FSData32(X + FX, Y + FY).B + (CLng(BSData32(X + BX, Y + BY).B) - FSData32(X + FX, Y + FY).B) * MaskRate
DData32(X + DX, Y + DY).B = Temp + (CLng(BSData32(X + BX, Y + BY).B) - Temp) * AlphaRate
Next X
Next Y
'返回数据
SetBitmapBits hDest, DInfo.bmWidth * DInfo.bmHeight * 4, DData32(0, 0)
Erase DData32, BSData32, FSData32, MData32
End If
End Sub
1、如果为 PictureBox 或 Form 可以传它们的 Image 属性 (IPictureDisp.Handle)
2、如果为其它控件或窗口,可以先用API GetDC 获取设备场景,再使用API GetCurrentObject 取得位图信息
3、如果为API CreateBitmap、CreateBitmapIndirect 等函数直接创建的内存位图,则直接传它们的返回值如果不传hMask或为0,效果类似于API alphablend
如果hMask是亮度差异为2的位图,效果类似与GIF的单色透明
如果hMask是亮度差异为256的位图,效果类似与PNG的256阶透明。
china2009
等 级:
发表于:2008-01-18 14:08:116楼 得分:0
真的没人知道吗?!
//冲你这句话,不少人就真的"不知道"了