dcsimg
Results 1 to 35 of 35

Thread: [RESOLVED] Fastest way to render transparent stdPictures or pngs to grid cells

Threaded View

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Sep 2012
    Posts
    1,682

    Resolved [RESOLVED] Fastest way to render transparent stdPictures or pngs to grid cells

    I need to quickly render a large number of small pictures in my grid cells, and the pictures need to be transparent to the grid backcolor. I'm ready to use the following code to achieve my purpose, I'd like to know if there is a simpler, more efficient way.

    Code:
    Private Sub DrawPicture(lpRect As RECT, Optional lBrushColor As Long = -1)
    
    '****************************************************************************
    ' draw the picture by calling the TransBlt routines                         *
    '****************************************************************************
    
       Dim tmpMaskColor     As Long
    
       ' --Draw picture
       If tmppic.Type = vbPicTypeIcon Then
          tmpMaskColor = TranslateColor(&HC0C0C0)
       Else
          tmpMaskColor = m_nMaskColor
       End If
       
       If Is32BitBMP(tmppic) Then
          TransBlt32 hDC, lpRect.Left, lpRect.Top, PicW, PicH, tmppic, lBrushColor
       Else
          TransBlt hDC, lpRect.Left, lpRect.Top, PicW, PicH, tmppic, tmpMaskColor, lBrushColor
       End If
       
    End Sub
    
    Private Sub TransBlt32(ByVal DstDC As Long, ByVal dstX As Long, ByVal dstY As Long, ByVal DstW As Long, ByVal DstH As Long, ByVal SrcPic As StdPicture, Optional ByVal BrushColor As Long = -1, Optional ByVal isGreyscale As Boolean = False)
    
       '****************************************************************************
       '* Routine : Renders 32 bit Bitmap                                          *
       '* Author  : Dana Seaman                                                    *
       '****************************************************************************
    
       Dim b                As Long, H As Long, f As Long, i As Long, newW As Long
       Dim TmpDC            As Long, TmpBmp As Long, TmpObj As Long
       Dim Sr2DC            As Long, Sr2Bmp As Long, Sr2Obj As Long
       Dim DataDest()       As RGBQUAD, DataSrc() As RGBQUAD
       Dim Info             As BITMAPINFO, BrushRGB As RGBQUAD, gCol As Long
       Dim hOldOb           As Long, PicEffect As enumPicEffect
       Dim SrcDC            As Long, tObj As Long, ttt As Long
       Dim bDisOpacity      As Byte
       Dim OverOpacity      As Byte
       Dim a2               As Long
       Dim a1               As Long
    
       If DstW = 0 Or DstH = 0 Then Exit Sub
       If SrcPic Is Nothing Then Exit Sub
    
       If m_ButtonState = eStateOver Then
          PicEffect = m_PicEffectonOver
       ElseIf m_ButtonState = eStateDown Then
          PicEffect = m_PicEffectonDown
       End If
       
       If Not m_bEnabled Then
          Select Case m_PicDisabledMode
          Case edpBlended
             bDisOpacity = 52
          Case edpGrayed
             bDisOpacity = m_PictureOpacity * 0.75
             isGreyscale = True
          End Select
       End If
          
       If m_ButtonState = eStateOver Then
          OverOpacity = m_PicOpacityOnOver
       End If
       
       SrcDC = CreateCompatibleDC(hDC)
    
       If DstW < 0 Then DstW = UserControl.ScaleX(SrcPic.Width, 8, UserControl.ScaleMode)
       If DstH < 0 Then DstH = UserControl.ScaleY(SrcPic.Height, 8, UserControl.ScaleMode)
    
       tObj = SelectObject(SrcDC, SrcPic)
    
       TmpDC = CreateCompatibleDC(SrcDC)
       Sr2DC = CreateCompatibleDC(SrcDC)
    
       TmpBmp = CreateCompatibleBitmap(DstDC, DstW, DstH)
       Sr2Bmp = CreateCompatibleBitmap(DstDC, DstW, DstH)
       TmpObj = SelectObject(TmpDC, TmpBmp)
       Sr2Obj = SelectObject(Sr2DC, Sr2Bmp)
    
       With Info.bmiHeader
          .biSize = Len(Info.bmiHeader)
          .biWidth = DstW
          .biHeight = DstH
          .biPlanes = 1
          .biBitCount = 32
          .biSizeImage = 4 * ((DstW * .biBitCount + 31) \ 32) * DstH
       End With
       ReDim DataDest(Info.bmiHeader.biSizeImage - 1)
       ReDim DataSrc(UBound(DataDest))
    
       BitBlt TmpDC, 0, 0, DstW, DstH, DstDC, dstX, dstY, vbSrcCopy
       BitBlt Sr2DC, 0, 0, DstW, DstH, SrcDC, 0, 0, vbSrcCopy
       GetDIBits TmpDC, TmpBmp, 0, DstH, DataDest(0), Info, 0
       GetDIBits Sr2DC, Sr2Bmp, 0, DstH, DataSrc(0), Info, 0
    
       If BrushColor <> -1 Then
          BrushRGB.rgbBlue = (BrushColor \ &H10000) Mod &H100
          BrushRGB.rgbGreen = (BrushColor \ &H100) Mod &H100
          BrushRGB.rgbRed = BrushColor And &HFF
       End If
    
       newW = DstW - 1
    
       For H = 0 To DstH - 1
          f = H * DstW
          For b = 0 To newW
             i = f + b
             If m_bEnabled Then
                 If m_ButtonState = eStateOver Then
                    a1 = (CLng(DataSrc(i).rgbAlpha) * OverOpacity) \ 255
                 Else
                    a1 = (CLng(DataSrc(i).rgbAlpha) * m_PictureOpacity) \ 255
                 End If
             Else
                a1 = (CLng(DataSrc(i).rgbAlpha) * bDisOpacity) \ 255
             End If
             a2 = 255 - a1
             With DataDest(i)
                If BrushColor <> -1 Then
                   If a1 = 255 Then
                      DataDest(i) = BrushRGB
                   ElseIf a1 > 0 Then
                      .rgbRed = (a2 * .rgbRed + a1 * BrushRGB.rgbRed) \ 256
                      .rgbGreen = (a2 * .rgbGreen + a1 * BrushRGB.rgbGreen) \ 256
                      .rgbBlue = (a2 * .rgbBlue + a1 * BrushRGB.rgbBlue) \ 256
                   End If
                Else
                   If isGreyscale Then
                      gCol = CLng(DataSrc(i).rgbRed * 0.3) + DataSrc(i).rgbGreen * 0.59 + DataSrc(i).rgbBlue * 0.11
                      If a1 = 255 Then
                         .rgbRed = gCol: .rgbGreen = gCol: .rgbBlue = gCol
                      ElseIf a1 > 0 Then
                         .rgbRed = (a2 * .rgbRed + a1 * gCol) \ 256
                         .rgbGreen = (a2 * .rgbGreen + a1 * gCol) \ 256
                         .rgbBlue = (a2 * .rgbBlue + a1 * gCol) \ 256
                      End If
                   Else
                      If a1 = 255 Then
                         If (PicEffect = epeLighter) Then
                            .rgbRed = aLighten(DataSrc(i).rgbRed)
                            .rgbGreen = aLighten(DataSrc(i).rgbGreen)
                            .rgbBlue = aLighten(DataSrc(i).rgbBlue)
                         ElseIf PicEffect = epeDarker Then
                            .rgbRed = aDarken(DataSrc(i).rgbRed)
                            .rgbGreen = aDarken(DataSrc(i).rgbGreen)
                            .rgbBlue = aDarken(DataSrc(i).rgbBlue)
                         Else
                            DataDest(i) = DataSrc(i)
                         End If
                      ElseIf a1 > 0 Then
                         If (PicEffect = epeLighter) Then
                            .rgbRed = (a2 * .rgbRed + a1 * aLighten(DataSrc(i).rgbRed)) \ 256
                            .rgbGreen = (a2 * .rgbGreen + a1 * aLighten(DataSrc(i).rgbGreen)) \ 256
                            .rgbBlue = (a2 * .rgbBlue + a1 * aLighten(DataSrc(i).rgbBlue)) \ 256
                         ElseIf PicEffect = epeDarker Then
                            .rgbRed = (a2 * .rgbRed + a1 * aDarken(DataSrc(i).rgbRed)) \ 256
                            .rgbGreen = (a2 * .rgbGreen + a1 * aDarken(DataSrc(i).rgbGreen)) \ 256
                            .rgbBlue = (a2 * .rgbBlue + a1 * aDarken(DataSrc(i).rgbBlue)) \ 256
                         Else
                            .rgbRed = (a2 * .rgbRed + a1 * DataSrc(i).rgbRed) \ 256
                            .rgbGreen = (a2 * .rgbGreen + a1 * DataSrc(i).rgbGreen) \ 256
                            .rgbBlue = (a2 * .rgbBlue + a1 * DataSrc(i).rgbBlue) \ 256
                         End If
                      End If
                   End If
                End If
             End With
          Next b
       Next H
    
       ' /--Paint it!
       SetDIBitsToDevice DstDC, dstX, dstY, DstW, DstH, 0, 0, 0, DstH, DataDest(0), Info, 0
    
       Erase DataDest, DataSrc
       DeleteObject SelectObject(TmpDC, TmpObj)
       DeleteObject SelectObject(Sr2DC, Sr2Obj)
       If SrcPic.Type = vbPicTypeIcon Then DeleteObject SelectObject(SrcDC, tObj)
       DeleteDC TmpDC
       DeleteDC Sr2DC
       DeleteObject tObj
       DeleteDC SrcDC
    
    End Sub
    
    Private Sub TransBlt(ByVal DstDC As Long, ByVal dstX As Long, ByVal dstY As Long, ByVal DstW As Long, ByVal DstH As Long, ByVal SrcPic As StdPicture, Optional ByVal TransColor As Long = -1, Optional ByVal BrushColor As Long = -1, Optional ByVal MonoMask As Boolean = False, Optional ByVal isGreyscale As Boolean = False)
    
       '****************************************************************************
       '* Routine : To make transparent and grayscale images
       '* Author  : Gonkuchi
       '
       '* Modified by Dana Seaman
       '****************************************************************************
    
       Dim b                As Long, H As Long, f As Long, i As Long, newW As Long
       Dim TmpDC            As Long, TmpBmp As Long, TmpObj As Long
       Dim Sr2DC            As Long, Sr2Bmp As Long, Sr2Obj As Long
       Dim DataDest()       As RGBTRIPLE, DataSrc() As RGBTRIPLE
       Dim Info             As BITMAPINFO, BrushRGB As RGBTRIPLE, gCol As Long
       Dim hOldOb           As Long, PicEffect As enumPicEffect
       Dim SrcDC            As Long, tObj As Long, ttt As Long
       Dim bDisOpacity      As Byte
       Dim OverOpacity      As Byte
       Dim a2               As Long
       Dim a1               As Long
    
       If DstW = 0 Or DstH = 0 Then Exit Sub
       If SrcPic Is Nothing Then Exit Sub
    
       If m_ButtonState = eStateOver Then
          PicEffect = m_PicEffectonOver
       ElseIf m_ButtonState = eStateDown Then
          PicEffect = m_PicEffectonDown
       End If
       
       If Not m_bEnabled Then
          Select Case m_PicDisabledMode
          Case edpBlended
             bDisOpacity = 52
          Case edpGrayed
             bDisOpacity = m_PictureOpacity * 0.75
             isGreyscale = True
          End Select
       End If
       
       If m_ButtonState = eStateOver Then
          OverOpacity = m_PicOpacityOnOver
       End If
    
       SrcDC = CreateCompatibleDC(hDC)
    
       If DstW < 0 Then DstW = UserControl.ScaleX(SrcPic.Width, 8, UserControl.ScaleMode)
       If DstH < 0 Then DstH = UserControl.ScaleY(SrcPic.Height, 8, UserControl.ScaleMode)
    
       If SrcPic.Type = vbPicTypeBitmap Then 'check if it's an icon or a bitmap
          tObj = SelectObject(SrcDC, SrcPic)
       Else
          Dim hBrush           As Long
          tObj = SelectObject(SrcDC, CreateCompatibleBitmap(DstDC, DstW, DstH))
          hBrush = CreateSolidBrush(TransColor)
          DrawIconEx SrcDC, 0, 0, SrcPic.handle, DstW, DstH, 0, hBrush, DI_NORMAL
          DeleteObject hBrush
       End If
    
       TmpDC = CreateCompatibleDC(SrcDC)
       Sr2DC = CreateCompatibleDC(SrcDC)
       TmpBmp = CreateCompatibleBitmap(DstDC, DstW, DstH)
       Sr2Bmp = CreateCompatibleBitmap(DstDC, DstW, DstH)
       TmpObj = SelectObject(TmpDC, TmpBmp)
       Sr2Obj = SelectObject(Sr2DC, Sr2Bmp)
       ReDim DataDest(DstW * DstH * 3 - 1)
       ReDim DataSrc(UBound(DataDest))
       With Info.bmiHeader
          .biSize = Len(Info.bmiHeader)
          .biWidth = DstW
          .biHeight = DstH
          .biPlanes = 1
          .biBitCount = 24
       End With
    
       BitBlt TmpDC, 0, 0, DstW, DstH, DstDC, dstX, dstY, vbSrcCopy
       BitBlt Sr2DC, 0, 0, DstW, DstH, SrcDC, 0, 0, vbSrcCopy
       GetDIBits TmpDC, TmpBmp, 0, DstH, DataDest(0), Info, 0
       GetDIBits Sr2DC, Sr2Bmp, 0, DstH, DataSrc(0), Info, 0
    
       If BrushColor > 0 Then
          BrushRGB.rgbBlue = (BrushColor \ &H10000) Mod &H100
          BrushRGB.rgbGreen = (BrushColor \ &H100) Mod &H100
          BrushRGB.rgbRed = BrushColor And &HFF
       End If
    
       ' --No Maskcolor to use
       If Not m_bUseMaskColor Then TransColor = -1
    
       newW = DstW - 1
    
       For H = 0 To DstH - 1
          f = H * DstW
          For b = 0 To newW
             i = f + b
             If m_ButtonState = eStateOver Then
                a1 = OverOpacity
             Else
                a1 = IIf(m_bEnabled, m_PictureOpacity, bDisOpacity)
             End If
             a2 = 255 - a1
             If GetNearestColor(hDC, CLng(DataSrc(i).rgbRed) + 256& * DataSrc(i).rgbGreen + 65536 * DataSrc(i).rgbBlue) <> TransColor Then
                With DataDest(i)
                   If BrushColor > -1 Then
                      If MonoMask Then
                         If (CLng(DataSrc(i).rgbRed) + DataSrc(i).rgbGreen + DataSrc(i).rgbBlue) <= 384 Then DataDest(i) = BrushRGB
                      Else
                         If a1 = 255 Then
                            DataDest(i) = BrushRGB
                         ElseIf a1 > 0 Then
                            .rgbRed = (a2 * .rgbRed + a1 * BrushRGB.rgbRed) \ 256
                            .rgbGreen = (a2 * .rgbGreen + a1 * BrushRGB.rgbGreen) \ 256
                            .rgbBlue = (a2 * .rgbBlue + a1 * BrushRGB.rgbBlue) \ 256
                         End If
                      End If
                   Else
                      If isGreyscale Then
                         gCol = CLng(DataSrc(i).rgbRed * 0.3) + DataSrc(i).rgbGreen * 0.59 + DataSrc(i).rgbBlue * 0.11
                         If a1 = 255 Then
                            .rgbRed = gCol: .rgbGreen = gCol: .rgbBlue = gCol
                         ElseIf a1 > 0 Then
                            .rgbRed = (a2 * .rgbRed + a1 * gCol) \ 256
                            .rgbGreen = (a2 * .rgbGreen + a1 * gCol) \ 256
                            .rgbBlue = (a2 * .rgbBlue + a1 * gCol) \ 256
                         End If
                      Else
                         If a1 = 255 Then
                            If PicEffect = epeLighter Then
                               .rgbRed = aLighten(DataSrc(i).rgbRed)
                               .rgbGreen = aLighten(DataSrc(i).rgbGreen)
                               .rgbBlue = aLighten(DataSrc(i).rgbBlue)
                            ElseIf PicEffect = epeDarker Then
                               .rgbRed = aDarken(DataSrc(i).rgbRed)
                               .rgbGreen = aDarken(DataSrc(i).rgbGreen)
                               .rgbBlue = aDarken(DataSrc(i).rgbBlue)
                            Else
                               DataDest(i) = DataSrc(i)
                            End If
                         ElseIf a1 > 0 Then
                            If (PicEffect = epeLighter) Then
                               .rgbRed = (a2 * .rgbRed + a1 * aLighten(DataSrc(i).rgbRed)) \ 256
                               .rgbGreen = (a2 * .rgbGreen + a1 * aLighten(DataSrc(i).rgbGreen)) \ 256
                               .rgbBlue = (a2 * .rgbBlue + a1 * aLighten(DataSrc(i).rgbBlue)) \ 256
                            ElseIf PicEffect = epeDarker Then
                               .rgbRed = (a2 * .rgbRed + a1 * aDarken(DataSrc(i).rgbRed)) \ 256
                               .rgbGreen = (a2 * .rgbGreen + a1 * aDarken(DataSrc(i).rgbGreen)) \ 256
                               .rgbBlue = (a2 * .rgbBlue + a1 * aDarken(DataSrc(i).rgbBlue)) \ 256
                            Else
                               .rgbRed = (a2 * .rgbRed + a1 * DataSrc(i).rgbRed) \ 256
                               .rgbGreen = (a2 * .rgbGreen + a1 * DataSrc(i).rgbGreen) \ 256
                               .rgbBlue = (a2 * .rgbBlue + a1 * DataSrc(i).rgbBlue) \ 256
                            End If
                         End If
                      End If
                   End If
                End With
             End If
          Next b
       Next H
    
       ' /--Paint it!
       SetDIBitsToDevice DstDC, dstX, dstY, DstW, DstH, 0, 0, 0, DstH, DataDest(0), Info, 0
    
       Erase DataDest, DataSrc
       DeleteObject SelectObject(TmpDC, TmpObj)
       DeleteObject SelectObject(Sr2DC, Sr2Obj)
       If SrcPic.Type = vbPicTypeIcon Then DeleteObject SelectObject(SrcDC, tObj)
       DeleteDC TmpDC
       DeleteDC Sr2DC
       DeleteObject tObj
       DeleteDC SrcDC
    
    End Sub
    I know that AlphaBlend (msimg32) and GdiAlphaBlend (gdi32.dll) can do similar work. In addition, I also know that LaVolpe's stdPicEx2 can achieve this functionality, but stdPicEx2 is too large for my grid control, and I'm not familiar with GdiPlus. I wonder if I can use gdi32 or Cairo to simply and quickly render pictures in grid cells.

    Any advice and suggestions would be greatly appreciated.
    Last edited by dreammanor; Jun 10th, 2018 at 09:45 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width