Results 1 to 24 of 24

Thread: [RESOLVED] [VB6] API DIBs - Change Image Colors

  1. #1

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Resolved [RESOLVED] [VB6] API DIBs - Change Image Colors

    by these page VB Graphics Programming: Part 3 (Advanced API): http://www.tannerhelland.com/vb6/vb-...programming-3/
    i build a procedure for change image colors. but by some reason isn't working
    The VB6 is closed. but it's showed a Windows error window.
    error message: ".... the memory can't be read..." and "...the memory can't be writen".
    heres the procedure:
    Code:
    Public Sub SetImageData(ByRef DstPictureBox As PictureBox, ByRef ImageData() As Byte, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
    
        For X = 0 To bm.bmHeight - 1
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(2, X, Y), ImageData(1, X, Y), ImageData(0, X, Y)) Then
                    RGBColor = RGBValues(NewColor)
                    ImageData(2, X, Y) = RGBColor.Red
                    ImageData(1, X, Y) = RGBColor.Green
                    ImageData(0, X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    
    Private Function RGBValues(Color As Long) As Color 'find the rgb color values of a color
        Dim ReturnColor As Color
        With ReturnColor
            .Red = Fix(Color And 255)
            .Green = Fix((Color And 65535) / 256)
            .Blue = Fix(Color / 65536)
        End With
        RGBValues = ReturnColor
    End Function
    now heres the project....
    i don't know why these error
    can anyone help me fix the error?
    thanks
    Attached Files Attached Files
    Last edited by joaquim; Nov 18th, 2009 at 04:34 PM.
    VB6 2D Sprite control

    To live is difficult, but we do it.

  2. #2
    Discovering Life Siddharth Rout's Avatar
    Join Date
    Feb 2005
    Location
    Mumbai, India
    Posts
    12,001

    Re: [VB6] API DIBs - Change Image Colors

    Try it with a normal jpeg image. with bit dept 24, frame count-1.

    I cannot test it right now as I don't have vb6 in the office. Can check it only when I get home...
    A good exercise for the Heart is to bend down and help another up...
    Please Mark your Thread "Resolved", if the query is solved


    MyGear:
    ★ CPU ★ Ryzen 5 5800X
    ★ GPU ★ NVIDIA GeForce RTX 3080 TI Founder Edition
    ★ RAM ★ G. Skill Trident Z RGB 32GB 3600MHz
    ★ MB ★ ASUS TUF GAMING X570 (WI-FI) ATX Gaming
    ★ Storage ★ SSD SB-ROCKET-1TB + SEAGATE 2TB Barracuda IHD
    ★ Cooling ★ NOCTUA NH-D15 CHROMAX BLACK 140mm + 10 of Noctua NF-F12 PWM
    ★ PSU ★ ANTEC HCG-1000-EXTREME 1000 Watt 80 Plus Gold Fully Modular PSU
    ★ Case ★ LIAN LI PC-O11 DYNAMIC XL ROG (BLACK) (G99.O11DXL-X)
    ★ Monitor ★ LG Ultragear 27" 240Hz Gaming Monitor
    ★ Keyboard ★ TVS Electronics Gold Keyboard
    ★ Mouse ★ Logitech G502 Hero

  3. #3
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    I see a few problems

    1. In your posted code above, shouldn't the For:Next loop be: For X = 0 to bm.bmWidth-1

    2. In your GetImageData, routine you are sizing your array incorrectly which is probably causing the crashes. Number of bytes for each row of a bitmap must be word aligned (divisible by 4). You cannot just assume that the following statement is correct for a 24 bit bitmap. Only if the width of the bitmap is divisible by 4 will it be correct else it will not be.
    Code:
    ' Wrong
    ReDim ImageData(0 To 2, 0 To bm.bmWidth - 1, 0 To bm.bmHeight - 1)
    
    
    ' added this function I use to word align any bitmap bit depth
    Public Function ByteAlignOnWord(ByVal bitDepth As Byte, ByVal Width As Long) As Long
        ' function to align any bit depth on dWord boundaries
        ByteAlignOnWord = (((Width * bitDepth) + &H1F&) And Not &H1F&) \ &H8&
    End Function
    
    ' now the ReDim may look like this
    ReDim ImageData(0 To 2, 0 To ByteAlignOnWord(24,bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    3. In your GetImageData() routine you should verify that the following line of code does not return zero:
    GetObject SrcPictureBox.Image, bmLen, bm

    4. Tip: The line "RGBColor = RGBValues(NewColor)" only needs to be executed one time. I would take it out of the loop.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    I see a few problems

    1. In your posted code above, shouldn't the For:Next loop be: For X = 0 to bm.bmWidth-1

    2. In your GetImageData, routine you are sizing your array incorrectly which is probably causing the crashes. Number of bytes for each row of a bitmap must be word aligned (divisible by 4). You cannot just assume that the following statement is correct for a 24 bit bitmap. Only if the width of the bitmap is divisible by 4 will it be correct else it will not be.
    Code:
    ' Wrong
    ReDim ImageData(0 To 2, 0 To bm.bmWidth - 1, 0 To bm.bmHeight - 1)
    
    
    ' added this function I use to word align any bitmap bit depth
    Public Function ByteAlignOnWord(ByVal bitDepth As Byte, ByVal Width As Long) As Long
        ' function to align any bit depth on dWord boundaries
        ByteAlignOnWord = (((Width * bitDepth) + &H1F&) And Not &H1F&) \ &H8&
    End Function
    
    ' now the ReDim may look like this
    ReDim ImageData(0 To 2, 0 To ByteAlignOnWord(24,bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    3. In your GetImageData() routine you should verify that the following line of code does not return zero:
    GetObject SrcPictureBox.Image, bmLen, bm

    4. Tip: The line "RGBColor = RGBValues(NewColor)" only needs to be executed one time. I would take it out of the loop.
    hi LaVolte
    now it's working.... thanks
    but i still have not a nice results
    my sub(with GetPixel() and SetPixel()), don't give me these result
    why?
    VB6 2D Sprite control

    To live is difficult, but we do it.

  5. #5
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    Can you post your updated SetImageData sub again?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    Can you post your updated SetImageData sub again?
    Code:
    'Routine to set an image's pixel information from an array dimensioned (rgb, x, y)
    Public Sub SetImageData(ByRef DstPictureBox As PictureBox, ByRef ImageData() As Byte, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
        
        RGBColor = RGBValues(NewColor)
        For X = 0 To bm.bmHeight - 1
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(2, X, Y), ImageData(1, X, Y), ImageData(0, X, Y)) Then
                    ImageData(2, X, Y) = RGBColor.Red
                    ImageData(1, X, Y) = RGBColor.Green
                    ImageData(0, X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    Code:
    'Routine to get an image's pixel information into an array dimensioned (rgb, x, y)
    Public Function GetImageData(ByRef SrcPictureBox As PictureBox, ByRef ImageData() As Byte) As Long
    
        
        'Now we fill up the bmi (Bitmap information variable) with all of the appropriate data
        bmi.bmHeader.bmSize = 40 'Size, in bytes, of the header (always 40)
        bmi.bmHeader.bmPlanes = 1 'Number of planes (always one)
        bmi.bmHeader.bmBitCount = 24 'Bits per pixel (always 24 for image processing)
        bmi.bmHeader.bmCompression = 0 'Compression: none or RLE (always zero)
    
        'Calculate the size of the bitmap type (in bytes)
        
        bmLen = Len(bm)
    
        'Get the picture box information from SrcPictureBox and put it into our 'bm' variable
        GetObject SrcPictureBox.Image, bmLen, bm
        If GetObject(SrcPictureBox.Image, bmLen, bm) = 0 Then
            GetImageData = 0
            Exit Function
        Else
            GetImageData = GetObject(SrcPictureBox.Image, bmLen, bm)
        End If
    
        'Build a correctly sized array.
        ReDim ImageData(0 To 2, 0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
        'Finish building the 'bmi' variable we want to pass to the GetDIBits call (the same variable we used above)
        bmi.bmHeader.bmWidth = bm.bmWidth
        bmi.bmHeader.bmHeight = bm.bmHeight
    
        'Now that we've completely filled up the 'bmi' variable, we use GetDIBits to take the data from SrcPictureBox and put it into the ImageData() array using the settings we specified in 'bmi'
        GetDIBits SrcPictureBox.hDC, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0, 0), bmi, 0
    
    End Function
    VB6 2D Sprite control

    To live is difficult, but we do it.

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    my post #3. The 1st item I mentioned. You did not fix that.

    Also you are calling this twice: GetObject SrcPictureBox.Image, bmLen, bm
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    my post #3. The 1st item I mentioned. You did not fix that.

    Also you are calling this twice: GetObject SrcPictureBox.Image, bmLen, bm
    my mistake
    i did it now, but still having the same problem
    Code:
    'Routine to set an image's pixel information from an array dimensioned (rgb, x, y)
    Public Sub SetImageData(ByRef DstPictureBox As PictureBox, ByRef ImageData() As Byte, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
        
        RGBColor = RGBValues(NewColor)
        For X = 0 To bm.bmWidth - 1
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(2, X, Y), ImageData(1, X, Y), ImageData(0, X, Y)) Then
                    ImageData(2, X, Y) = RGBColor.Red
                    ImageData(1, X, Y) = RGBColor.Green
                    ImageData(0, X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    VB6 2D Sprite control

    To live is difficult, but we do it.

  9. #9

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    my post #3. The 1st item I mentioned. You did not fix that.

    Also you are calling this twice: GetObject SrcPictureBox.Image, bmLen, bm
    Code:
    'Routine to get an image's pixel information into an array dimensioned (rgb, x, y)
    Public Function GetImageData(ByRef SrcPictureBox As PictureBox, ByRef ImageData() As Byte) As Long
    
        
        'Now we fill up the bmi (Bitmap information variable) with all of the appropriate data
        bmi.bmHeader.bmSize = 40 'Size, in bytes, of the header (always 40)
        bmi.bmHeader.bmPlanes = 1 'Number of planes (always one)
        bmi.bmHeader.bmBitCount = 24 'Bits per pixel (always 24 for image processing)
        bmi.bmHeader.bmCompression = 0 'Compression: none or RLE (always zero)
    
        'Calculate the size of the bitmap type (in bytes)
        
        bmLen = Len(bm)
    
        'Get the picture box information from SrcPictureBox and put it into our 'bm' variable
        GetImageData = GetObject(SrcPictureBox.Image, bmLen, bm)
        If GetImageData = 0 Then Exit Function
        
        'Build a correctly sized array.
        ReDim ImageData(0 To 2, 0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
        'Finish building the 'bmi' variable we want to pass to the GetDIBits call (the same variable we used above)
        bmi.bmHeader.bmWidth = bm.bmWidth
        bmi.bmHeader.bmHeight = bm.bmHeight
    
        'Now that we've completely filled up the 'bmi' variable, we use GetDIBits to take the data from SrcPictureBox and put it into the ImageData() array using the settings we specified in 'bmi'
        GetDIBits SrcPictureBox.hDC, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0, 0), bmi, 0
    
    End Function
    now i fix that
    but i still having the pixels problems
    VB6 2D Sprite control

    To live is difficult, but we do it.

  10. #10
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    Sorry, I should have caught this....

    Your loop is looping thru only a 3rd of the array. Here are some recommended changes
    Code:
        Dim X As Long, Y As Long
        Dim lScanWidth As Long ' << added
    
        lScanWidth = ByteAlignOnWord(24, bm.bmWidth) ' << added
        RGBColor = RGBValues(NewColor)
        For X = 0 To lScanWidth - 1 Step 3 ' << modified
    ....
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  11. #11

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    Sorry, I should have caught this....

    Your loop is looping thru only a 3rd of the array. Here are some recommended changes
    Code:
        Dim X As Long, Y As Long
        Dim lScanWidth As Long ' << added
    
        lScanWidth = ByteAlignOnWord(24, bm.bmWidth) ' << added
        RGBColor = RGBValues(NewColor)
        For X = 0 To lScanWidth - 1 Step 3 ' << modified
    ....
    now change less pixels
    VB6 2D Sprite control

    To live is difficult, but we do it.

  12. #12
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    Yep, your 3D array is throwing my calculations off.
    Here is how to do it with a 2D array. You can use this or modify your For:Next loop to work with 3D arrays. Your choice

    2D array requires the following line changes
    Code:
    ReDim ImageData(0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
    GetDIBits SrcPictureBox.hDC, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0
    
    ' replace loop like so:
        For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 1 Step 3
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(X, Y), ImageData(X, Y), ImageData(X, Y)) Then
                    ImageData(X + 2, Y) = RGBColor.Red
                    ImageData(X + 1, Y) = RGBColor.Green
                    ImageData(X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
    StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    Yep, your 3D array is throwing my calculations off.
    Here is how to do it with a 2D array. You can use this or modify your For:Next loop to work with 3D arrays. Your choice

    2D array requires the following line changes
    Code:
    ReDim ImageData(0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
    GetDIBits SrcPictureBox.hDC, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0
    
    ' replace loop like so:
        For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 1 Step 3
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(X, Y), ImageData(X, Y), ImageData(X, Y)) Then
                    ImageData(X + 2, Y) = RGBColor.Red
                    ImageData(X + 1, Y) = RGBColor.Green
                    ImageData(X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
    StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
    i'm still having some problems in result
    Code:
    'Routine to get an image's pixel information into an array dimensioned (rgb, x, y)
    Public Function GetImageData(ByRef SrcPictureBox As PictureBox, ByRef ImageData() As Byte) As Long
        
        'Now we fill up the bmi (Bitmap information variable) with all of the appropriate data
        bmi.bmHeader.bmSize = 40 'Size, in bytes, of the header (always 40)
        bmi.bmHeader.bmPlanes = 1 'Number of planes (always one)
        bmi.bmHeader.bmBitCount = 24 'Bits per pixel (always 24 for image processing)
        bmi.bmHeader.bmCompression = 0 'Compression: none or RLE (always zero)
    
        'Calculate the size of the bitmap type (in bytes)
        
        bmLen = Len(bm)
    
        'Get the picture box information from SrcPictureBox and put it into our 'bm' variable
        GetImageData = GetObject(SrcPictureBox.Image, bmLen, bm)
        If GetImageData = 0 Then Exit Function
        
        'Build a correctly sized array.
        ReDim ImageData(0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
        'Finish building the 'bmi' variable we want to pass to the GetDIBits call (the same variable we used above)
        bmi.bmHeader.bmWidth = bm.bmWidth
        bmi.bmHeader.bmHeight = bm.bmHeight
    
        'Now that we've completely filled up the 'bmi' variable, we use GetDIBits to take the data from SrcPictureBox and put it into the ImageData() array using the settings we specified in 'bmi'
        GetDIBits SrcPictureBox.hDC, SrcPictureBox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0
    End Function
    
    'Routine to set an image's pixel information from an array dimensioned (rgb, x, y)
    Public Sub SetImageData(ByRef DstPictureBox As PictureBox, ByRef ImageData() As Byte, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
    
        RGBColor = RGBValues(NewColor)
        For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 1 Step 3
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(X, Y), ImageData(X, Y), ImageData(X, Y)) Then
                    ImageData(X + 2, Y) = RGBColor.Red
                    ImageData(X + 1, Y) = RGBColor.Green
                    ImageData(X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    VB6 2D Sprite control

    To live is difficult, but we do it.

  14. #14

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    see the image result.
    has you can see, not only the eyes was changed. but some part of the head too
    why?
    is about the variables types?
    oldcolor and newcolor are long, and ImageData() is byte.
    heres how i use it:
    Code:
    Private Sub Command1_Click()
        Dim imgData() As Byte
        GetImageData Picture1, imgData()
        SetImageData Picture2, imgData(), Picture3.BackColor, Picture4.BackColor
    End Sub
    Attached Images Attached Images  
    Last edited by joaquim; Nov 19th, 2009 at 04:51 PM.
    VB6 2D Sprite control

    To live is difficult, but we do it.

  15. #15

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    i can do it(with a correct result) with these sub:
    Code:
    Public Sub ChangeColor(Picture As Object, OldColor As Long, NewColor As Long)
        Dim mDC As Long
        Dim mBMP As Long
        Dim PosX As Long
        Dim PosY As Long
        Dim PixelColor As Long
        Dim ScaleMode As Integer
        Dim AutoRedraw As Boolean
        
        ScaleMode = Picture.ScaleMode
        Picture.ScaleMode = 3
        AutoRedraw = Picture.AutoRedraw
        Picture.AutoRedraw = True
        mDC = CreateCompatibleDC(Picture.hdc)
        mBMP = CreateCompatibleBitmap(Picture.hdc, Picture.ScaleWidth, Picture.ScaleHeight)
        SelectObject mDC, mBMP
        BitBlt mDC, 0, 0, Picture.ScaleWidth, Picture.ScaleHeight, Picture.hdc, 0, 0, vbSrcCopy
        For PosX = 0 To Picture.ScaleWidth
            For PosY = 0 To Picture.ScaleHeight
                PixelColor = GetPixel(mDC, PosX, PosY)
                If PixelColor <> -1 Then
                    If PixelColor = OldColor Then
                        SetPixel mDC, PosX, PosY, NewColor
                    End If
                End If
            Next PosY
        Next PosX
        BitBlt Picture.hdc, 0, 0, Picture.ScaleWidth, Picture.ScaleHeight, mDC, 0, 0, vbSrcCopy
        Picture.ScaleMode = ScaleMode
        Picture.Picture = Picture.Image
        Picture.AutoRedraw = AutoRedraw
        DeleteObject mBMP
        DeleteDC mDC
    End Sub
    but i need speed. and the only way is the DIB code
    i can control these entire code
    do what i need with pixels
    but like i said, i want speed
    i show you these for you catch more what i mean
    thank you for help me my friend... thanks
    VB6 2D Sprite control

    To live is difficult, but we do it.

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    1. For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 3 Step 3

    2. If OldColor = RGB(ImageData(X + 2, Y), ImageData(X + 1, Y), ImageData(X, Y)) Then
    Last edited by LaVolpe; Nov 20th, 2009 at 10:26 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  17. #17

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    1. For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 3 Step 3

    2. If OldColor = RGB(ImageData(X + 2, Y), ImageData(X + 1, Y), ImageData(X, Y)) Then
    sorry in 2nd point
    i didn't get it
    now it's working fine
    thanks
    now i can working with DIB's easy
    Code:
    'Routine to set an image's pixel information from an array dimensioned (rgb, x, y)
    Public Sub SetImageData(ByRef DstPictureBox As PictureBox, ByRef ImageData() As Byte, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
    
        RGBColor = RGBValues(NewColor)
        For X = 0 To ByteAlignOnWord(bmi.bmHeader.bmBitCount, bm.bmWidth) - 3 Step 3
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(X + 2, Y), ImageData(X + 1, Y), ImageData(X, Y)) Then
                    ImageData(X + 2, Y) = RGBColor.Red
                    ImageData(X + 1, Y) = RGBColor.Green
                    ImageData(X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hDC, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    VB6 2D Sprite control

    To live is difficult, but we do it.

  18. #18

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    now i'm trying put it in my Sprite 2D control
    but i catch 1 error. before works 100% well, now i catch 1 error
    sometimes i don't understand

    in a module:
    Code:
    'Some functions for work with bitmaps\Images
    Option Explicit
    
    Public Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
    Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    Public Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
    Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Public Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
    Public Declare Function BitBlt Lib "gdi32" (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 xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Public Declare Function AlphaBlend Lib "msimg32" (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 xSrc As Long, ByVal ySrc As Long, ByVal widthSrc As Long, ByVal heightSrc As Long, ByVal blendFunct As Long) As Boolean
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Public Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    
    Private Type BITMAPINFOHEADER
      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
       rgbAlpha As Byte
    End Type
    
    Private Type BITMAPINFO
       bmHeader As BITMAPINFOHEADER
       bmColors(0 To 255) As RGBQUAD
    End Type
    
    Private 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 Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef 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 BITMAPINFOHEADER, 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 BITMAPINFOHEADER, ByVal wUsage As Long) As Long
    
    Private Type Color
        Red As Long
        Green As Long
        Blue As Long
    End Type
    
    
    Dim hbmp As Long
    Dim bih As BITMAPINFOHEADER
    Dim bmpBits() As Long
    
    Private Const DIB_RGB_COLORS As Long = 0
    Public Const SRCCOPY = &HCC0020
    
    'Routine to set an image's pixel information from an array dimensioned (rgb, x, y)
    Public Sub DIBChangeImageColor(ByRef SrcPicturebox As PictureBox, ByRef DstPictureBox As PictureBox, ByRef OldColor As Long, ByRef NewColor As Long)
        Dim X As Long, Y As Long
        Dim ImageData() As Byte
        Dim bmLen As Long
        Dim bm As BITMAP
        Dim bmi As BITMAPINFO
        Dim RGBColor As Color
        
        'Now we fill up the bmi (Bitmap information variable) with all of the appropriate data
        bmi.bmHeader.biSize = 40  'Size, in bytes, of the header (always 40)
        bmi.bmHeader.biPlanes = 1 'Number of planes (always one)
        bmi.bmHeader.biBitCount = 24 'Bits per pixel (always 24 for image processing)
        bmi.bmHeader.biCompression = 0 'Compression: none or RLE (always zero)
        
        'Calculate the size of the bitmap type (in bytes)
        bmLen = Len(bm)
        
        GetObject SrcPicturebox.Image, bmLen, bm
        
        'Build a correctly sized array.
        ReDim ImageData(0 To ByteAlignOnWord(24, bm.bmWidth) - 1, 0 To bm.bmHeight - 1)
    
        'Finish building the 'bmi' variable we want to pass to the GetDIBits call (the same variable we used above)
        bmi.bmHeader.biWidth = bm.bmWidth 'now it's bi and not bm
        bmi.bmHeader.biHeight = bm.bmHeight 'now it's bi and not bm
    
        'Now that we've completely filled up the 'bmi' variable, we use GetDIBits to take the data from SrcPictureBox and put it into the ImageData() array using the settings we specified in 'bmi'
        GetDIBits SrcPicturebox.hdc, SrcPicturebox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0 'bmi is give me the error:( "byref argument type mismatch"
        
        RGBColor = RGBValues(NewColor)
        For X = 0 To ByteAlignOnWord(bmi.bmHeader.biBitCount, bm.biWidth) - 3 Step 3
            For Y = 0 To bm.bmHeight - 1
                If OldColor = RGB(ImageData(X + 2, Y), ImageData(X + 1, Y), ImageData(X, Y)) Then
                    ImageData(X + 2, Y) = RGBColor.Red
                    ImageData(X + 1, Y) = RGBColor.Green
                    ImageData(X, Y) = RGBColor.Blue
                End If
            Next Y
        Next X
    
        'Now that we've built the temporary header, we use StretchDIBits to take the data from the ImageData() array and put it into SrcPictureBox using the settings specified in 'bmi' (the StretchDIBits call should be on one continuous line)
        StretchDIBits DstPictureBox.hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, bm.bmWidth, bm.bmHeight, ImageData(0, 0), bmi, 0, vbSrcCopy
    
        'Since this doesn't automatically initialize AutoRedraw, we have to do it manually
        'Note: always keep AutoRedraw as 'True' when using DIB sections. Otherwise, you WILL get unpredictable results.
        If DstPictureBox.AutoRedraw = True Then
            DstPictureBox.Picture = DstPictureBox.Image
            DstPictureBox.Refresh
        End If
    
    End Sub
    please help me correct these last error
    in these line:
    Code:
    GetDIBits SrcPicturebox.hdc, SrcPicturebox.Image, 0, bm.bmHeight, ImageData(0, 0), bmi, 0 'bmi is give me the error:( "byref argument type mismatch"
    error message: "compiler error: byref argument type mismatch".
    thanks
    VB6 2D Sprite control

    To live is difficult, but we do it.

  19. #19
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    hmmm

    1. You added: Dim bmi As BITMAPINFO
    2. The API has: ... lpBits As Any, lpBI As BITMAPINFOHEADER, ByVal wUsage As Long ...
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  20. #20

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    hmmm

    1. You added: Dim bmi As BITMAPINFO
    2. The API has: ... lpBits As Any, lpBI As BITMAPINFOHEADER, ByVal wUsage As Long ...
    sorry. now i'm building 100% new Graphic module(with your help... thanks) for put in my Sprite control.

    now i need to catch the real image size:
    Code:
    Private Declare Function GetBitmapDimensionEx Lib "gdi32" (ByVal hBitmap As Long, lpDimension As Size) As Long
    Private Type Size
            cx As Long
            cy As Long
    End Type
    
    Dim bitmapsize As Size
    
    Public Sub ImageSize(ByRef Picture As Control)
        GetBitmapDimensionEx Picture.Picture.Handle, bitmapsize
        Debug.Print bitmapsize.cx
    End Sub
    my problem here is that i only recive 0(zero)
    why?
    Attached Files Attached Files
    Last edited by joaquim; Nov 21st, 2009 at 01:12 PM.
    VB6 2D Sprite control

    To live is difficult, but we do it.

  21. #21
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: [VB6] API DIBs - Change Image Colors

    Per MSDN's documentation on that function...
    The GetBitmapDimensionEx function retrieves the dimensions of a compatible bitmap. The retrieved dimensions must have been set by the SetBitmapDimensionEx function
    If you are wanting the size of a picture object, use ScaleX/ScaleY
    Code:
    Width = ScaleX(Control.Picture.Width, vbHimetric, vbPixels)
    Height = ScaleY(Control.Picture.Height, vbHimetric, vbPixels)
    You could also use APIs if you were interested in image sizes based on just a bitmap handle.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  22. #22

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by LaVolpe View Post
    Per MSDN's documentation on that function...
    If you are wanting the size of a picture object, use ScaleX/ScaleY
    Code:
    Width = ScaleX(Control.Picture.Width, vbHimetric, vbPixels)
    Height = ScaleY(Control.Picture.Height, vbHimetric, vbPixels)
    You could also use APIs if you were interested in image sizes based on just a bitmap handle.
    works fine
    thanks
    VB6 2D Sprite control

    To live is difficult, but we do it.

  23. #23
    New Member
    Join Date
    Nov 2009
    Posts
    2

    Re: [RESOLVED] [VB6] API DIBs - Change Image Colors

    How to save the image???
    Thx

  24. #24

    Thread Starter
    PowerPoster joaquim's Avatar
    Join Date
    Apr 2007
    Posts
    3,959

    Re: [RESOLVED] [VB6] API DIBs - Change Image Colors

    Quote Originally Posted by bewolf View Post
    How to save the image???
    Thx
    Code:
    SavePicture objectname.picture, "filename"
    VB6 2D Sprite control

    To live is difficult, but we do it.

Posting Permissions

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



Click Here to Expand Forum to Full Width