www.pudn.com > 200863019405335.rar > cDIBSection.cls


VERSION 1.0 CLASS 
BEGIN 
  MultiUse = -1  'True 
  Persistable = 0  'NotPersistable 
  DataBindingBehavior = 0  'vbNone 
  DataSourceBehavior  = 0  'vbNone 
  MTSTransactionMode  = 0  'NotAnMTSObject 
END 
Attribute VB_Name = "cDIBSection" 
Attribute VB_GlobalNameSpace = False 
Attribute VB_Creatable = True 
Attribute VB_PredeclaredId = False 
Attribute VB_Exposed = False 
 
Option Explicit 
 
Private m_hDIb As Long 
Private m_hBmpOld As Long 
Private m_hDC As Long 
Private m_lPtr As Long 
Private m_tBI As BITMAPINFO 
 
Public Function CreateDIB( _ 
        ByVal lHDC As Long, _ 
        ByVal lWidth As Long, _ 
        ByVal lHeight As Long, _ 
        ByRef hDib As Long _ 
    ) As Boolean 
    With m_tBI.bmiHeader 
        .biSize = Len(m_tBI.bmiHeader) 
        .biWidth = lWidth 
        .biHeight = lHeight 
        .biPlanes = 1 
        .biBitCount = 24 
        .biCompression = BI_RGB 
        .biSizeImage = BytesPerScanLine * .biHeight 
    End With 
    hDib = CreateDIBSection( _ 
            lHDC, _ 
            m_tBI, _ 
            DIB_RGB_COLORS, _ 
            m_lPtr, _ 
            0, 0) 
    CreateDIB = (hDib <> 0) 
End Function 
Public Function CreateFromPicture( _ 
        ByRef picThis As StdPicture _ 
    ) 
Dim lHDC As Long 
Dim lhDCDesktop As Long 
Dim lhBmpOld As Long 
Dim tBMP As Bitmap 
     
    GetObjectAPI picThis.handle, Len(tBMP), tBMP 
    If (Create(tBMP.bmWidth, tBMP.bmHeight)) Then 
        lhDCDesktop = GetDC(GetDesktopWindow()) 
        If (lhDCDesktop <> 0) Then 
            lHDC = CreateCompatibleDC(lhDCDesktop) 
            DeleteDC lhDCDesktop 
            If (lHDC <> 0) Then 
                lhBmpOld = SelectObject(lHDC, picThis.handle) 
                LoadPictureBlt lHDC 
                SelectObject lHDC, lhBmpOld 
                DeleteObject lHDC 
            End If 
        End If 
    End If 
End Function 
Public Function Create( _ 
        ByVal lWidth As Long, _ 
        ByVal lHeight As Long _ 
    ) As Boolean 
    ClearUp 
    m_hDC = CreateCompatibleDC(0) 
    If (m_hDC <> 0) Then 
        If (CreateDIB(m_hDC, lWidth, lHeight, m_hDIb)) Then 
            m_hBmpOld = SelectObject(m_hDC, m_hDIb) 
            Create = True 
        Else 
            DeleteObject m_hDC 
            m_hDC = 0 
        End If 
    End If 
End Function 
Public Property Get BytesPerScanLine() As Long 
    ' 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 ClearUp() 
    If (m_hDC <> 0) Then 
        If (m_hDIb <> 0) Then 
            SelectObject m_hDC, m_hBmpOld 
            DeleteObject m_hDIb 
        End If 
        DeleteObject 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