📄 cdibsection.cls
字号:
' Scans must align on dword boundaries:
BytesPerScanLine = (m_tBI.bmiHeader.biWidth * 3 + 3) And &HFFFFFFFC
End Property
Public Property Get Width() As Long
Width = m_tBI.bmiHeader.biWidth
End Property
Public Property Get Height() As Long
Height = m_tBI.bmiHeader.biHeight
End Property
Public Sub LoadPictureBlt( _
ByVal lhDC As Long, _
Optional ByVal lSrcLeft As Long = 0, _
Optional ByVal lSrcTop As Long = 0, _
Optional ByVal lSrcWidth As Long = -1, _
Optional ByVal lSrcHeight As Long = -1, _
Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
)
If lSrcWidth < 0 Then lSrcWidth = m_tBI.bmiHeader.biWidth
If lSrcHeight < 0 Then lSrcHeight = m_tBI.bmiHeader.biHeight
BitBlt m_hDC, 0, 0, lSrcWidth, lSrcHeight, lhDC, lSrcLeft, lSrcTop, eRop
End Sub
Public Sub PaintPicture( _
ByVal lhDC As Long, _
Optional ByVal lDestLeft As Long = 0, _
Optional ByVal lDestTop As Long = 0, _
Optional ByVal lDestWidth As Long = -1, _
Optional ByVal lDestHeight As Long = -1, _
Optional ByVal lSrcLeft As Long = 0, _
Optional ByVal lSrcTop As Long = 0, _
Optional ByVal eRop As RasterOpConstants = vbSrcCopy _
)
If (lDestWidth < 0) Then lDestWidth = m_tBI.bmiHeader.biWidth
If (lDestHeight < 0) Then lDestHeight = m_tBI.bmiHeader.biHeight
BitBlt lhDC, lDestLeft, lDestTop, lDestWidth, lDestHeight, m_hDC, lSrcLeft, lSrcTop, eRop
End Sub
Public Property Get hdc() As Long
hdc = m_hDC
End Property
Public Property Get hDib() As Long
hDib = m_hDIb
End Property
Public Property Get DIBSectionBitsPtr() As Long
DIBSectionBitsPtr = m_lPtr
End Property
Public Sub RandomiseBits( _
Optional ByVal bGray As Boolean = False _
)
Dim bDib() As Byte
Dim x As Long, y As Long
Dim lC As Long
Dim tSA As SAFEARRAY2D
Dim xEnd As Long
' Get the bits in the from DIB section:
With tSA
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = m_tBI.bmiHeader.biHeight
.Bounds(1).lLbound = 0
.Bounds(1).cElements = BytesPerScanLine()
.pvData = m_lPtr
End With
CopyMemory ByVal VarPtrArray(bDib()), VarPtr(tSA), 4
' random:
Randomize Timer
xEnd = (Width - 1) * 3
If (bGray) Then
For y = 0 To m_tBI.bmiHeader.biHeight - 1
For x = 0 To xEnd Step 3
lC = Rnd * 255
bDib(x, y) = lC
bDib(x + 1, y) = lC
bDib(x + 2, y) = lC
Next x
Next y
Else
For x = 0 To xEnd Step 3
For y = 0 To m_tBI.bmiHeader.biHeight - 1
bDib(x, y) = 0
bDib(x + 1, y) = Rnd * 255
bDib(x + 2, y) = Rnd * 255
Next y
Next x
End If
' Clear the temporary array descriptor
' (This does not appear to be necessary, but
' for safety do it anyway)
CopyMemory ByVal VarPtrArray(bDib), 0&, 4
End Sub
Public Sub ClearUp()
If (m_hDC <> 0) Then
If (m_hDIb <> 0) Then
SelectObject m_hDC, m_hBmpOld
DeleteObject m_hDIb
End If
DeleteDC m_hDC
End If
m_hDC = 0: m_hDIb = 0: m_hBmpOld = 0: m_lPtr = 0
End Sub
Public Function Resample( _
ByVal lNewHeight As Long, _
ByVal lNewWidth As Long _
) As cDIBSection
Dim cDib As cDIBSection
Set cDib = New cDIBSection
If cDib.Create(lNewWidth, lNewHeight) Then
If (lNewWidth <> m_tBI.bmiHeader.biWidth) Or (lNewHeight <> m_tBI.bmiHeader.biHeight) Then
' Change in size, do resample:
ResampleDib cDib
Else
' No size change so just return a copy:
cDib.LoadPictureBlt m_hDC
End If
Set Resample = cDib
End If
End Function
Private Function ResampleDib(ByRef cDibTo As cDIBSection) As Boolean
Dim bDibFrom() As Byte
Dim bDibTo() As Byte
Dim tSAFrom As SAFEARRAY2D
Dim tSATo As SAFEARRAY2D
' Get the bits in the from DIB section:
With tSAFrom
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = m_tBI.bmiHeader.biHeight
.Bounds(1).lLbound = 0
.Bounds(1).cElements = BytesPerScanLine()
.pvData = m_lPtr
End With
CopyMemory ByVal VarPtrArray(bDibFrom()), VarPtr(tSAFrom), 4
' Get the bits in the to DIB section:
With tSATo
.cbElements = 1
.cDims = 2
.Bounds(0).lLbound = 0
.Bounds(0).cElements = cDibTo.Height
.Bounds(1).lLbound = 0
.Bounds(1).cElements = cDibTo.BytesPerScanLine()
.pvData = cDibTo.DIBSectionBitsPtr
End With
CopyMemory ByVal VarPtrArray(bDibTo()), VarPtr(tSATo), 4
Dim xScale As Single
Dim yScale As Single
Dim x As Long, y As Long, xEnd As Long, xOut As Long
Dim fX As Single, fY As Single
Dim ifY As Long, ifX As Long
Dim dX As Single, dy As Single
Dim r As Long, r1 As Single, r2 As Single, r3 As Single, r4 As Single
Dim g As Long, g1 As Single, g2 As Single, g3 As Single, g4 As Single
Dim b As Long, b1 As Single, b2 As Single, b3 As Single, b4 As Single
Dim ir1 As Long, ig1 As Long, ib1 As Long
Dim ir2 As Long, ig2 As Long, ib2 As Long
xScale = (Width - 1) / cDibTo.Width
yScale = (Height - 1) / cDibTo.Height
xEnd = cDibTo.Width - 1
For y = 0 To cDibTo.Height - 1
fY = y * yScale
ifY = Int(fY)
dy = fY - ifY
For x = 0 To xEnd
fX = x * xScale
ifX = Int(fX)
dX = fX - ifX
ifX = ifX * 3
' Interpolate using the four nearest pixels in the source
b1 = bDibFrom(ifX, ifY): g1 = bDibFrom(ifX + 1, ifY): r1 = bDibFrom(ifX + 2, ifY)
b2 = bDibFrom(ifX + 3, ifY): g2 = bDibFrom(ifX + 4, ifY): r2 = bDibFrom(ifX + 5, ifY)
b3 = bDibFrom(ifX, ifY + 1): g3 = bDibFrom(ifX + 1, ifY + 1): r3 = bDibFrom(ifX + 2, ifY + 1)
b4 = bDibFrom(ifX + 3, ifY + 1): g4 = bDibFrom(ifX + 4, ifY + 1): r4 = bDibFrom(ifX + 5, ifY + 1)
' Interplate in x direction:
ir1 = r1 * (1 - dy) + r3 * dy: ig1 = g1 * (1 - dy) + g3 * dy: ib1 = b1 * (1 - dy) + b3 * dy
ir2 = r2 * (1 - dy) + r4 * dy: ig2 = g2 * (1 - dy) + g4 * dy: ib2 = b2 * (1 - dy) + b4 * dy
' Interpolate in y:
r = ir1 * (1 - dX) + ir2 * dX: g = ig1 * (1 - dX) + ig2 * dX: b = ib1 * (1 - dX) + ib2 * dX
' Set output:
If (r < 0) Then r = 0
If (r > 255) Then r = 255
If (g < 0) Then g = 0
If (g > 255) Then g = 255
If (b < 0) Then b = 0
If (b > 255) Then
b = 255
End If
xOut = x * 3
bDibTo(xOut, y) = b
bDibTo(xOut + 1, y) = g
bDibTo(xOut + 2, y) = r
Next x
Next y
' Clear the temporary array descriptor
' (This does not appear to be necessary, but
' for safety do it anyway)
CopyMemory ByVal VarPtrArray(bDibFrom), 0&, 4
CopyMemory ByVal VarPtrArray(bDibTo), 0&, 4
End Function
Private Sub Class_Terminate()
ClearUp
End Sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -