Public Type mRGB
R As Byte
G As Byte
B As Byte
A As Byte
End Type
Public Const BI_RGB = 0&
Public Const DIB_RGB_COLORS = 0
Public Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Public Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As mRGB
End Type
Public Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Public Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Public Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Public Declare Function GetCurrentObject Lib "gdi32" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Function Morph2D(x As Long, y As Long, NumRow As Long) As Long
Morph2D = (y - 1) * NumRow + x
End Function
Public Function AlphaBltFast(ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal hAlphaDC As Long, ByVal xSrc As Long, ByVal ySrc As Long)
Dim I As Long
Dim j As Long
Dim TempR As Long
Dim TempG As Long
Dim TempB As Long
Dim AlphaVal As mRGB
Dim SrcVal As mRGB
Dim DestVal As mRGB
Dim dBitmap As Long
Dim dBMP As BITMAP
Dim dPic() As mRGB
Dim dMem As BITMAPINFO
Dim sBitmap As Long
Dim sBMP As BITMAP
Dim sPic() As mRGB
Dim sMem As BITMAPINFO
Dim aBitmap As Long
Dim aBMP As BITMAP
Dim aPic() As mRGB
Dim aMem As BITMAPINFO
dBitmap = GetCurrentObject(hDestDC, OBJ_BITMAP)
sBitmap = GetCurrentObject(hSrcDC, OBJ_BITMAP)
aBitmap = GetCurrentObject(hAlphaDC, OBJ_BITMAP)
GetObjectAPI dBitmap, Len(dBMP), dBMP
GetObjectAPI sBitmap, Len(sBMP), sBMP
GetObjectAPI aBitmap, Len(aBMP), aBMP
With dMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(dMem.bmiHeader)
.biWidth = dBMP.bmWidth
.biHeight = dBMP.bmHeight
ReDim Preserve dPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With
GetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS
With sMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(sMem.bmiHeader)
.biWidth = sBMP.bmWidth
.biHeight = sBMP.bmHeight
ReDim Preserve sPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With
GetDIBits hSrcDC, sBitmap, 0, sBMP.bmHeight, sPic(0), sMem, DIB_RGB_COLORS
With aMem.bmiHeader
.biBitCount = 32
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(aMem.bmiHeader)
.biWidth = aBMP.bmWidth
.biHeight = aBMP.bmHeight
ReDim Preserve aPic(0 To (.biWidth * .biHeight) - 1) As mRGB
End With
GetDIBits hAlphaDC, aBitmap, 0, aBMP.bmHeight, aPic(0), aMem, DIB_RGB_COLORS
For j = y To y + (nHeight - 1)
For I = x To x + (nWidth - 1)
DestVal = dPic(Morph2D(I, dBMP.bmHeight - j, dBMP.bmWidth)) 'dColour.L = GetPixel(hDestDC, I, J)
SrcVal = sPic(Morph2D(I - x + xSrc, sBMP.bmHeight - (j - y + ySrc), sBMP.bmWidth)) 'sColour.L = GetPixel(hSrcDC, I - x + xSrc, J - y + ySrc)
AlphaVal = aPic(Morph2D(I - x + xSrc, aBMP.bmHeight - (j - y + ySrc), aBMP.bmWidth)) 'aColour.L = GetPixel(hAlphaDC, I - x + xSrc, J - y + ySrc)
AlphaVal.R = 255 - AlphaVal.R
AlphaVal.G = 255 - AlphaVal.G
AlphaVal.B = 255 - AlphaVal.B
TempR = (AlphaVal.R * CLng(SrcVal.R + 256 - DestVal.R)) / 256 + DestVal.R - AlphaVal.R
TempG = (AlphaVal.G * CLng(SrcVal.G + 256 - DestVal.G)) / 256 + DestVal.G - AlphaVal.G
TempB = (AlphaVal.B * CLng(SrcVal.B + 256 - DestVal.B)) / 256 + DestVal.B - AlphaVal.B
'// Explanation: VB uses R, G, B order. Bitmap uses B, G, R, A order. Therefore, we must switch around the B and the R values.
With dPic(Morph2D(I, dBMP.bmHeight - j, dBMP.bmWidth))
.B = TempR
.G = TempG
.R = TempB
End With
Next I
Next j
SetDIBits hDestDC, dBitmap, 0, dBMP.bmHeight, dPic(0), dMem, DIB_RGB_COLORS
DeleteObject dBitmap
ReDim dPic(0)
DeleteObject sBitmap
ReDim sPic(0)
DeleteObject aBitmap
ReDim aPic(0)
End Function