Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Transparent picture boxes?
#15
Okay, I found one working method, problem is, I can't seem to get it to work with more than one picture box.

I'm going to post the code, with a semi tut on how to implement it to get it working, but mind you, it's very simple. But also, don't forget, it only works with a single picture box at the moment.

Code:

Add this code to any form:
Code:
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal x1 As Long, ByVal y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private 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
Private 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
Private Type BITMAP '14 bytes
    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
Private Type RGBQUAD
    rgbBlue As Byte
    rgbGreen As Byte
    rgbRed As Byte
    rgbReserved As Byte
End Type
Private Type BITMAPINFO
    bmiHeader As BITMAPINFOHEADER
    bmiColors As RGBQUAD
End Type
Private Const DIB_RGB_COLORS = 0&
Private Const BI_RGB = 0&

Private Const pixR As Integer = 3
Private Const pixG As Integer = 2
Private Const pixB As Integer = 1
Private Sub UnRGB(ByRef color As Long, ByRef r As Byte, ByRef g As Byte, ByRef b As Byte)
    r = color And &HFF&
    g = (color And &HFF00&) \ &H100&
    b = (color And &HFF0000) \ &H10000
End Sub
' Restrict the form to its "transparent" pixels.
Private Sub TrimPicture(ByVal pic As PictureBox, ByVal transparent_color As Long)
Const RGN_OR = 2
Dim bitmap_info As BITMAPINFO
Dim pixels() As Byte
Dim bytes_per_scanLine As Integer
Dim pad_per_scanLine As Integer
Dim transparent_r As Byte
Dim transparent_g As Byte
Dim transparent_b As Byte
Dim wid As Integer
Dim hgt As Integer
Dim X As Integer
Dim Y As Integer
Dim start_x As Integer
Dim stop_x As Integer
Dim combined_rgn As Long
Dim new_rgn As Long

    ' Prepare the bitmap description.
    With bitmap_info.bmiHeader
        .biSize = 40
        .biWidth = picTest.ScaleWidth
        ' Use negative height to scan top-down.
        .biHeight = -picTest.ScaleHeight
        .biPlanes = 1
        .biBitCount = 32
        .biCompression = BI_RGB
        bytes_per_scanLine = ((((.biWidth * .biBitCount) + 31) \ 32) * 4)
        pad_per_scanLine = bytes_per_scanLine - (((.biWidth * .biBitCount) + 7) \ 8)
        .biSizeImage = bytes_per_scanLine * Abs(.biHeight)
    End With

    ' Load the bitmap's data.
    wid = picTest.ScaleWidth
    hgt = picTest.ScaleHeight
    ReDim pixels(1 To 4, 0 To wid - 1, 0 To hgt - 1)
    GetDIBits picTest.hdc, picTest.Image, _
        0, picTest.ScaleHeight, pixels(1, 0, 0), _
        bitmap_info, DIB_RGB_COLORS

    ' Break the transparent color into its components.
    UnRGB transparent_color, transparent_r, transparent_g, transparent_b

    ' Create the PictureBox's regions.
    For Y = 0 To hgt - 1
        ' Create a region for this row.
        X = 1
        Do While X < wid
            start_x = 0
            stop_x = 0

            ' Find the next non-transparent column.
            Do While X < wid
                If pixels(pixR, X, Y)  transparent_r Or _
                   pixels(pixG, X, Y)  transparent_g Or _
                   pixels(pixB, X, Y)  transparent_b _
                Then
                    Exit Do
                End If
                X = X + 1
            Loop
            start_x = X

            ' Find the next transparent column.
            Do While X < wid
                If pixels(pixR, X, Y) = transparent_r And _
                   pixels(pixG, X, Y) = transparent_g And _
                   pixels(pixB, X, Y) = transparent_b _
                Then
                    Exit Do
                End If
                X = X + 1
            Loop
            stop_x = X

            ' Make a region from start_x to stop_x.
            If start_x < wid Then
                If stop_x >= wid Then stop_x = wid - 1

                ' Create the region.
                new_rgn = CreateRectRgn( _
                    start_x, Y, stop_x, Y + 1)

                ' Add it to what we have so far.
                If combined_rgn = 0 Then
                    combined_rgn = new_rgn
                Else
                    CombineRgn combined_rgn, _
                        combined_rgn, new_rgn, RGN_OR
                    DeleteObject new_rgn
                End If
            End If
        Loop
    Next Y
    
    ' Restrict the PictureBox to the region.
    SetWindowRgn pic.hWnd, combined_rgn, True
    DeleteObject combined_rgn
End Sub

Private Sub pictest_Click()
    Unload Me
End Sub


Private Sub Form_Load()
    ' Center the form.
    Move (Screen.Width - Width) / 2, (Screen.Height - Height) / 2

    ' Move the picture on top of the other controls.
    picTest.ZOrder
    picTest.ScaleMode = vbPixels
    picTest.AutoRedraw = True
    picTest.Picture = picTest.Image

    ' Trim the picture.
    TrimPicture picTest, &HFF00FF
End Sub

Create a picture box and name it picTest.

Then make sure you have an image that has something that can be transparent on it. Either change the &HFF00FF to the hex of your color, or us the RGB 255,0,255 as the color to make transparent.

Run the project, should work.

Now, what I am asking is, can someone help me get this to work with more than one picture box?
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 2 Guest(s)