none
[VB2010] - why these code don't change the color?

    Question

  • Private Function ConvertBackColor(ByRef source As Bitmap, _
                                       ByVal NewBackColor As Color) As Bitmap
            Dim c As Color
            Dim clrColor As Color
            c = source.GetPixel(0, 0)
            
            For y = 0 To source.Height - 1
                For x = 0 To source.Width - 1
                    clrColor = source.GetPixel(x, y)
                    If clrColor = c Then source.SetPixel(x, y, NewBackColor)
                Next
            Next
            Return source
            source.Dispose()
        End Function

    these code see the backcolor pixel(0,0) and change it to another color(just changes the backcolor). but by some reason these don't happens:(

    can anyone advice me?

    Friday, January 25, 2013 10:09 PM

Answers

  • Works in red too.


    You've taught me everything I know but not everything you know.

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:41 PM
    Saturday, January 26, 2013 12:31 PM

  • I made a little function for you that uses LockBits(faster than get/set pixel) to change your background color.

    Here is a link to the project:

    Using LockBits In Visual Basic to swap one color with another(Format32bppArgb)

    Here is the main function:

        Private Function SwapColors(ByVal Source As Bitmap, ByVal NewColor As Color, ByVal OldColor As Color) As Bitmap
            If Not Source.PixelFormat = PixelFormat.Format32bppArgb Then
                Dim Converted As New Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb)
                Dim Graphics As Graphics = Graphics.FromImage(Converted)
                Graphics.DrawImage(Source, New Rectangle(0, 0, Source.Width, Source.Height), _
                                   0, 0, Source.Width, Source.Height, GraphicsUnit.Pixel)
                Source = Converted
            End If
            Dim rect As New Rectangle(0, 0, Source.Width, Source.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = Source.LockBits(rect, _
                Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat)
            Dim ptr As IntPtr = bmpData.Scan0
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * Source.Height
            Dim rgbValues(bytes - 1) As Byte
            Marshal.Copy(ptr, rgbValues, 0, bytes)
            Dim Blue, Green, Red, Alpha As Byte
            Dim CurrentPixel As Color
            For I = 0 To (bmpData.Stride * Source.Height) - 1 Step 4
                Blue = rgbValues(I) : Green = rgbValues(I + 1)
                Red = rgbValues(I + 2) : Alpha = rgbValues(I + 3)
                CurrentPixel = Color.FromArgb(Alpha, Red, Green, Blue)
                If CurrentPixel = OldColor Then
                    Alpha = NewColor.A : Red = NewColor.R
                    Green = NewColor.G : Blue = NewColor.B
                End If
                rgbValues(I) = Blue : rgbValues(I + 1) = Green
                rgbValues(I + 2) = Red : rgbValues(I + 3) = Alpha
            Next
            Marshal.Copy(rgbValues, 0, ptr, bytes)
            Source.UnlockBits(bmpData)
            Return Source
        End Function


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 6:49 PM
  • Paul,

    In my perception Cabalinho did already what you wrote in your last message. 

    He placed his full class inside this thread, which shows much more elements which are useful to everybody who tries to make a color image Black and White like he wrote. 

    Therefore I hope a moderator will mark the by me proposed reply from him as answer.


    Success
    Cor

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:40 PM
    Saturday, January 26, 2013 7:22 PM
  • thanks to all

    i use these method for iniciate all properties and now works fine:

    Public Sub AddBitmap(ByRef Source As Bitmap)
            SourceBitmap = New Bitmap(Source)
            clrBackColor = SourceBitmap.GetPixel(0, 0)
            clrOriginalBackColor = clrBackColor
            clrTransparentColor = clrBackColor
            blnTransparent = False
            blnBlackAndWhite = False
            intOpacity = 255
            diwDrawImageWay = DrawImageWays.Normal
            mrMirror = Mirrorr.None
            clrNewColor = clrBackColor
            clrOldColor = clrBackColor
            intRotate = 0
        End Sub

    thanks for all;)

    can 'Mark as Answer' for both?

    because both of you help me so much;)

    thanks

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:38 PM
    Saturday, January 26, 2013 7:57 PM

All replies

  • The code works properly, so your problem is probably in the way that you are using the returned bitmap, or it is because you are disposing of the bitmap after you have returned it.
    Friday, January 25, 2013 10:23 PM
  • The code works properly, so your problem is probably in the way that you are using the returned bitmap, or it is because you are disposing of the bitmap after you have returned it.

    i have others functions, in same way and works normaly;)

    these code don't change the colors:(

    Friday, January 25, 2013 10:26 PM
  • I copied your function, and called it. It not only returns a bitmap with colours changed, but as source is passed ByRef, it also changes the colours in the original bitmap.

    Dim myBmp As New Bitmap(Me.Icon.ToBitmap)
    Dim newBmp As Bitmap = ConvertBackColor(myBmp, Color.Black)
    PictureBox1.Image = myBmp 'PictureBox1 shows new colours
    PictureBox2.Image = newBmp 'PictureBox2 shows new colours
    

    Your function only changes the colour of pixels that are the same colour as the one at (0, 0). So if you do not notice a change, perhaps there are very few pixels in the bitmap that are the same colour as the one at location (0, 0).

    Friday, January 25, 2013 10:36 PM
  • It's working form me I suppose

    Public Class Form1
    
        Dim Test As New Bitmap("C:\Users\John\Desktop\White.Png")
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        End Sub
    
    
        Private Function ConvertBackColor(ByRef source As Bitmap, ByVal NewBackColor As Color) As Bitmap
            Dim c As Color
            Dim clrColor As Color
            c = source.GetPixel(0, 0)
    
            For y = 0 To source.Height - 1
                For x = 0 To source.Width - 1
                    clrColor = source.GetPixel(x, y)
                    If clrColor = c Then source.SetPixel(x, y, NewBackColor)
                Next
            Next
            Return source
            source.Dispose()
        End Function
    
        Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Test.SetPixel(1, 1, Color.Black)
            Panel1.BackgroundImage = Test
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Panel1.BackgroundImage = ConvertBackColor(Test, Color.Black)
            Panel1.Refresh()
        End Sub
    
    End Class
    


    You've taught me everything I know but not everything you know.

    Friday, January 25, 2013 11:09 PM
  • Return source source.Dispose()

    these code see the backcolor pixel(0,0) and change it to another color(just changes the backcolor). but by some reason these don't happens:(

    can anyone advice me?

    Just a little extra piece of information for you, since you "Return Source", source.dispose will never be called, because "Return Source" exits the function before you ever arrive at the next line of code(which is source.dispose).

    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.



    Saturday, January 26, 2013 3:57 AM
  • It's working form me I suppose

    Public Class Form1
    
        Dim Test As New Bitmap("C:\Users\John\Desktop\White.Png")
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
        End Sub
    
    
        Private Function ConvertBackColor(ByRef source As Bitmap, ByVal NewBackColor As Color) As Bitmap
            Dim c As Color
            Dim clrColor As Color
            c = source.GetPixel(0, 0)
    
            For y = 0 To source.Height - 1
                For x = 0 To source.Width - 1
                    clrColor = source.GetPixel(x, y)
                    If clrColor = c Then source.SetPixel(x, y, NewBackColor)
                Next
            Next
            Return source
            source.Dispose()
        End Function
    
        Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Test.SetPixel(1, 1, Color.Black)
            Panel1.BackgroundImage = Test
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Panel1.BackgroundImage = ConvertBackColor(Test, Color.Black)
            Panel1.Refresh()
        End Sub
    
    End Class


    You've taught me everything I know but not everything you know.

    do me a favor, try use anothers colors, instead black;)

    Dim s As clsGraphics
    
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            s = New clsGraphics
            s.AddBitmap(PictureBox1.Image)
            s.Rotate = CInt(TextBox1.Text)
            s.Transparent = CheckBox1.CheckState
            's.TransparentColor = PictureBox2.BackColor
            s.Opacity = CInt(TextBox2.Text)
            s.BlackAndWhite = CheckBox2.CheckState
            s.Mirror = ComboBox2.SelectedIndex
            s.DrawImageWay = ComboBox1.SelectedIndex
            s.BackColor = Color.Blue
            Me.Refresh()
            s.DrawBitmap(Me, CInt(TextBox3.Text), CInt(TextBox4.Text))
    
        End Sub

    i must refresh before draw it or the image is draw 1 after another(seen both images);)

    if you refresh after, you lose what you draw(i have tested);)

    • Edited by Cambalinho Saturday, January 26, 2013 12:18 PM
    Saturday, January 26, 2013 12:14 PM
  • Return source source.Dispose()

    these code see the backcolor pixel(0,0) and change it to another color(just changes the backcolor). but by some reason these don't happens:(

    can anyone advice me?

    Just a little extra piece of information for you, since you "Return Source", source.dispose will never be called, because "Return Source" exits the function before you ever arrive at the next line of code(which is source.dispose).

    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.



    i didn't knew about that... thanks;)

    i normaly use dispose for clean memory, like you know;)

    Saturday, January 26, 2013 12:20 PM
  • Works in red too.


    You've taught me everything I know but not everything you know.

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:41 PM
    Saturday, January 26, 2013 12:31 PM
  • Works in red too.


    You've taught me everything I know but not everything you know.

    :(:(

    then why isn't working for me?:(:(

    Public Sub DrawBitmap(ByVal Device As Control, Optional ByRef PosX As Integer = 0, Optional ByRef PosY As Integer = 0)
            Dim X As Integer
            Dim Y As Integer
            Dim c As Color
            Dim luma As Integer
    
            ghpGraphics = Device.CreateGraphics
    
            SourceBitmap = ConvertBackColor(SourceBitmap, clrBackColor)
            If clrNewColor <> clrOldColor Then SourceBitmap = ConvertColors(SourceBitmap, clrNewColor, clrOldColor)
    
            If clrTransparentColor = Color.Empty Then clrTransparentColor = SourceBitmap.GetPixel(0, 0)
            SourceBitmap = RotateImage(SourceBitmap, intRotate)
            If blnBlackAndWhite = True Then
                SourceBitmap = Grayscale(SourceBitmap)
                If blnTransparent = True Then
                    c = clrTransparentColor
                    luma = CInt(c.R * 0.3 + c.G * 0.59 + c.B * 0.11)
                    c = Color.FromArgb(luma, luma, luma)
                    SourceBitmap.MakeTransparent(c)
                End If
            Else
                SourceBitmap.MakeTransparent(clrTransparentColor)
            End If
    
            If mrMirror = Mirrorr.None Then
                'do nothing
            ElseIf mrMirror = Mirrorr.Horizontal Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipX)
            ElseIf mrMirror = Mirrorr.Vertical Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY)
            ElseIf mrMirror = Mirrorr.HorizontalVertical Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipXY)
            End If
    
            If intOpacity > 0 Then SourceBitmap = ConvertOpacity(SourceBitmap, intOpacity, clrTransparentColor)
            If diwDrawImageWay = DrawImageWays.Tiled Then
                For Y = 0 To Device.ClientSize.Height Step SourceBitmap.Height
                    For X = 0 To Device.ClientSize.Width Step SourceBitmap.Width
                        ghpGraphics.DrawImage(SourceBitmap, X, Y)
                    Next
                Next
            ElseIf diwDrawImageWay = DrawImageWays.Stretch Then
                ghpGraphics.DrawImage(SourceBitmap, 0, 0, Device.ClientSize.Width, Device.ClientSize.Height)
            ElseIf diwDrawImageWay = DrawImageWays.Normal Then
                ghpGraphics.DrawImage(SourceBitmap, PosX, PosY)
            End If
            ghpGraphics.Dispose()
        End Sub

    what i'm doing wrong?:(


    • Edited by Cambalinho Saturday, January 26, 2013 12:59 PM
    Saturday, January 26, 2013 12:44 PM
  • i didn't knew about that... thanks;)

    i normaly use dispose for clean memory, like you know;)

    The other thing I just realized is that you're providing "source" ByRef, therefore you really don't need to make your method a function, instead you should make it a sub, because ByRef means that it's modified inside your method by reference, meaning that the actual instance that you passed as a parameter is modified both inside and outside of your method. Hope that makes sense. The other thing is that you should use Bitmap.Lockbits instead of the notoriously slow GetPixel and SetPixel methods. I will get you a Lockbits example soon.


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    Saturday, January 26, 2013 2:44 PM
  • i didn't knew about that... thanks;)

    i normaly use dispose for clean memory, like you know;)

    Another thing if you're providing source ByRef to your method, then if you dispose it inside your method, because it was provided ByRef, it will be disposed outside of your method as well.

    read this:

    http://msdn.microsoft.com/en-us/library/c84t73c2(v=vs.71).aspx


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 2:50 PM
  • i didn't knew about that... thanks;)

    i normaly use dispose for clean memory, like you know;)

    Another thing if you're providing source ByRef to your method, then if you dispose it inside your method, because it was provided ByRef, it will be disposed outside of your method as well.

    read this:

    http://msdn.microsoft.com/en-us/library/c84t73c2(v=vs.71).aspx


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles

    *This post does not reflect the opinion of Microsoft, or its employees.


    i don't understand why these code don't works:(

    can i share these code(entire project) here by link?

    Saturday, January 26, 2013 3:27 PM
  • You can upload your zipped project to your skydrive and share the link here

    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    Saturday, January 26, 2013 4:05 PM
  • You can upload your zipped project to your skydrive and share the link here

    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    http://www.mediafire.com/?11u79bdvwvd7388

    sorry the debug and release exe, but if theres a problem, please tell me;)

    heres the entire code. in form you have the almost options in my  Graphic class. but in code(in button) the backcolor must be blue. just click in button and see the results. the class you have the DrawBitmap() method, in  5 and 6 lines of code, i call that change color sub... now it's diferent(just a litle) but you understand the basic;)

    please tell me why these sub don't works:(

    thanks for all

    Saturday, January 26, 2013 4:19 PM
  • nice contribution, I tested it and does what it should do.


    Success
    Cor

    Saturday, January 26, 2013 4:27 PM
  • nice contribution, I tested it and does what it should do.


    Success
    Cor

    i love be more simple;)

    but wait for next thing hehehe;)

    i will rebuild my 2D Sprite control in VB2010;)

    it's a control for draw images(for games), with several games events(joystick, colision and others). and can be used like a picturebox;)

    to me show the black color... but i choose blue:(

    Saturday, January 26, 2013 4:37 PM
  • i can't put an image here.. just the link:(

    http://www.mediafire.com/view/?8abohyw0ib1ryh2

    • Edited by Cambalinho Saturday, January 26, 2013 4:59 PM put the image
    Saturday, January 26, 2013 4:55 PM

  • I made a little function for you that uses LockBits(faster than get/set pixel) to change your background color.

    Here is a link to the project:

    Using LockBits In Visual Basic to swap one color with another(Format32bppArgb)

    Here is the main function:

        Private Function SwapColors(ByVal Source As Bitmap, ByVal NewColor As Color, ByVal OldColor As Color) As Bitmap
            If Not Source.PixelFormat = PixelFormat.Format32bppArgb Then
                Dim Converted As New Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb)
                Dim Graphics As Graphics = Graphics.FromImage(Converted)
                Graphics.DrawImage(Source, New Rectangle(0, 0, Source.Width, Source.Height), _
                                   0, 0, Source.Width, Source.Height, GraphicsUnit.Pixel)
                Source = Converted
            End If
            Dim rect As New Rectangle(0, 0, Source.Width, Source.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = Source.LockBits(rect, _
                Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat)
            Dim ptr As IntPtr = bmpData.Scan0
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * Source.Height
            Dim rgbValues(bytes - 1) As Byte
            Marshal.Copy(ptr, rgbValues, 0, bytes)
            Dim Blue, Green, Red, Alpha As Byte
            Dim CurrentPixel As Color
            For I = 0 To (bmpData.Stride * Source.Height) - 1 Step 4
                Blue = rgbValues(I) : Green = rgbValues(I + 1)
                Red = rgbValues(I + 2) : Alpha = rgbValues(I + 3)
                CurrentPixel = Color.FromArgb(Alpha, Red, Green, Blue)
                If CurrentPixel = OldColor Then
                    Alpha = NewColor.A : Red = NewColor.R
                    Green = NewColor.G : Blue = NewColor.B
                End If
                rgbValues(I) = Blue : rgbValues(I + 1) = Green
                rgbValues(I + 2) = Red : rgbValues(I + 3) = Alpha
            Next
            Marshal.Copy(rgbValues, 0, ptr, bytes)
            Source.UnlockBits(bmpData)
            Return Source
        End Function


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 6:49 PM

  • I made a little function for you that uses LockBits(faster than get/set pixel) to change your background color.

    Here is a link to the project:

    Using LockBits In Visual Basic to swap one color with another(Format32bppArgb)

    Here is the main function:

        Private Function SwapColors(ByVal Source As Bitmap, ByVal NewColor As Color, ByVal OldColor As Color) As Bitmap
            If Not Source.PixelFormat = PixelFormat.Format32bppArgb Then
                Dim Converted As New Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb)
                Dim Graphics As Graphics = Graphics.FromImage(Converted)
                Graphics.DrawImage(Source, New Rectangle(0, 0, Source.Width, Source.Height), _
                                   0, 0, Source.Width, Source.Height, GraphicsUnit.Pixel)
                Source = Converted
            End If
            Dim OldAlpha As Byte = OldColor.A
            Dim OldRed As Byte = OldColor.R
            Dim OldGreen As Byte = OldColor.G
            Dim OldBlue As Byte = OldColor.B
            Dim rect As New Rectangle(0, 0, Source.Width, Source.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = Source.LockBits(rect, _
                Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat)
            Dim ptr As IntPtr = bmpData.Scan0
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * Source.Height
            Dim rgbValues(bytes - 1) As Byte
            Marshal.Copy(ptr, rgbValues, 0, bytes)
            For I = 0 To (bmpData.Stride * Source.Height) - 1 Step 4
                Dim Blue As Byte = rgbValues(I)
                Dim Green As Byte = rgbValues(I + 1)
                Dim Red As Byte = rgbValues(I + 2)
                Dim Alpha As Byte = rgbValues(I + 3)
                Dim CurrentPixel As Color = Color.FromArgb(Alpha, Red, Green, Blue)
                If CurrentPixel = OldColor Then
                    Alpha = NewColor.A
                    Red = NewColor.R
                    Green = NewColor.G
                    Blue = NewColor.B
                End If
                rgbValues(I) = Blue
                rgbValues(I + 1) = Green
                rgbValues(I + 2) = Red
                rgbValues(I + 3) = Alpha
            Next
            Marshal.Copy(rgbValues, 0, ptr, bytes)
            Source.UnlockBits(bmpData)
            Return Source
        End Function


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    i recive 4 errors:

    'Marshal' is not declared. It may be inaccessible due to its protection level.
    'PixelFormat' is not declared. It may be inaccessible due to its protection level.

    why?

    Saturday, January 26, 2013 6:58 PM
  • i recive 4 errors:

    'Marshal' is not declared. It may be inaccessible due to its protection level.
    'PixelFormat' is not declared. It may be inaccessible due to its protection level.

    why?

    Follow the suggested fixes in the designer(add these imports)

    I also suggest downloading the example I posted a link to, so you can test it as provided, then when you understand, migrate it to your project

    Imports System.Drawing.Imaging
    Imports System.Runtime.InteropServices


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.



    Saturday, January 26, 2013 7:02 PM

  • I made a little function for you that uses LockBits(faster than get/set pixel) to change your background color.

    Here is a link to the project:

    Using LockBits In Visual Basic to swap one color with another(Format32bppArgb)

    Here is the main function:

        Private Function SwapColors(ByVal Source As Bitmap, ByVal NewColor As Color, ByVal OldColor As Color) As Bitmap
            If Not Source.PixelFormat = PixelFormat.Format32bppArgb Then
                Dim Converted As New Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb)
                Dim Graphics As Graphics = Graphics.FromImage(Converted)
                Graphics.DrawImage(Source, New Rectangle(0, 0, Source.Width, Source.Height), _
                                   0, 0, Source.Width, Source.Height, GraphicsUnit.Pixel)
                Source = Converted
            End If
            Dim OldAlpha As Byte = OldColor.A
            Dim OldRed As Byte = OldColor.R
            Dim OldGreen As Byte = OldColor.G
            Dim OldBlue As Byte = OldColor.B
            Dim rect As New Rectangle(0, 0, Source.Width, Source.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = Source.LockBits(rect, _
                Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat)
            Dim ptr As IntPtr = bmpData.Scan0
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * Source.Height
            Dim rgbValues(bytes - 1) As Byte
            Marshal.Copy(ptr, rgbValues, 0, bytes)
            For I = 0 To (bmpData.Stride * Source.Height) - 1 Step 4
                Dim Blue As Byte = rgbValues(I)
                Dim Green As Byte = rgbValues(I + 1)
                Dim Red As Byte = rgbValues(I + 2)
                Dim Alpha As Byte = rgbValues(I + 3)
                Dim CurrentPixel As Color = Color.FromArgb(Alpha, Red, Green, Blue)
                If CurrentPixel = OldColor Then
                    Alpha = NewColor.A
                    Red = NewColor.R
                    Green = NewColor.G
                    Blue = NewColor.B
                End If
                rgbValues(I) = Blue
                rgbValues(I + 1) = Green
                rgbValues(I + 2) = Red
                rgbValues(I + 3) = Alpha
            Next
            Marshal.Copy(rgbValues, 0, ptr, bytes)
            Source.UnlockBits(bmpData)
            Return Source
        End Function


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    i recive 4 errors:

    'Marshal' is not declared. It may be inaccessible due to its protection level.
    'PixelFormat' is not declared. It may be inaccessible due to its protection level.

    why?

    Follow the suggested fixes in the designer(add these imports)

    Imports System.Drawing.Imaging
    Imports System.Runtime.InteropServices


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    i don't understand these function, for now, but i will;)

    i give up... help.. you have my entire project.... tell me why still not working:(

    :(


    i still recive the black color:(
    • Edited by Cambalinho Saturday, January 26, 2013 7:07 PM
    Saturday, January 26, 2013 7:06 PM

  • i don't understand these function, for now, but i will;)

    i give up... help.. you have my entire project.... tell me why still not working:(

    :(


    i still recive the black color:(

    I figure if I can put a lengthy amount of my time into helping you, you could put at least that much effort into helping yourself.

    If you don't understand something, I am more than willing to explain, but I will not simply "fix you project for you". So please increase your level of participation in your own problem, and I will be happy to continue. In other words, explain what you don't understand, ask for clarification on specific things.


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 7:10 PM

  • i don't understand these function, for now, but i will;)

    i give up... help.. you have my entire project.... tell me why still not working:(

    :(


    i still recive the black color:(

    I figure if I can put a lengthy amount of my time into helping you, you could put at least that much effort into helping yourself.

    If you don't understand something, I am more than willing to explain, but I will not simply "fix you project for you". So please increase your level of participation in your own problem, and I will be happy to continue.


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    Dim s As clsGraphics 'my class

     s = New clsGraphics
     s.AddBitmap(PictureBox1.Image)

    the bitmapt is puted to class:

    Public Sub AddBitmap(ByRef Source As Bitmap)
            SourceBitmap = New Bitmap(Source)
            clrBackColor = SourceBitmap.GetPixel(0, 0)
            clrOriginalBackColor = SourceBitmap.GetPixel(0, 0)
        End Sub

    ....................

    s.backcolor=color.blue

    s.DrawBitmap(Me, CInt(TextBox3.Text), CInt(TextBox4.Text))

    the image is draw it in that position:

    but see what is inside:

     Public Sub DrawBitmap(ByVal Device As Control, Optional ByRef PosX As Integer = 0, Optional ByRef PosY As Integer = 0)
            Dim X As Integer
            Dim Y As Integer
            Dim c As Color
            Dim luma As Integer

            ghpGraphics = Device.CreateGraphics

            

            If clrTransparentColor = Color.Empty Then clrTransparentColor = SourceBitmap.GetPixel(0, 0)
            SourceBitmap = RotateImage(SourceBitmap, intRotate)
            If clrBackColor <> clrOriginalBackColor Then SourceBitmap = SwapColors(SourceBitmap, clrOriginalBackColor, clrBackColor)


            If clrNewColor <> clrOldColor Then SourceBitmap = SwapColors(SourceBitmap, clrNewColor, clrOldColor)

    .......

    these 2 last 'if's' aren't executed:(

    and i don't know why:(

    but the rest work normaly:

     Public Sub DrawBitmap(ByVal Device As Control, Optional ByRef PosX As Integer = 0, Optional ByRef PosY As Integer = 0)
            Dim X As Integer
            Dim Y As Integer
            Dim c As Color
            Dim luma As Integer

            ghpGraphics = Device.CreateGraphics

            

            If clrTransparentColor = Color.Empty Then clrTransparentColor = SourceBitmap.GetPixel(0, 0)
            SourceBitmap = RotateImage(SourceBitmap, intRotate)
            If clrBackColor <> clrOriginalBackColor Then SourceBitmap = SwapColors(SourceBitmap, clrOriginalBackColor, clrBackColor)


            If clrNewColor <> clrOldColor Then SourceBitmap = SwapColors(SourceBitmap, clrNewColor, clrOldColor)
            If blnBlackAndWhite = True Then
                SourceBitmap = Grayscale(SourceBitmap)
                If blnTransparent = True Then
                    c = clrTransparentColor
                    luma = CInt(c.R * 0.3 + c.G * 0.59 + c.B * 0.11)
                    c = Color.FromArgb(luma, luma, luma)
                    SourceBitmap.MakeTransparent(c)
                End If
            Else
                SourceBitmap.MakeTransparent(clrTransparentColor)
            End If

            If mrMirror = Mirrorr.None Then
                'do nothing
            ElseIf mrMirror = Mirrorr.Horizontal Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipX)
            ElseIf mrMirror = Mirrorr.Vertical Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY)
            ElseIf mrMirror = Mirrorr.HorizontalVertical Then
                SourceBitmap.RotateFlip(RotateFlipType.RotateNoneFlipXY)
            End If

            If intOpacity > 0 Then SourceBitmap = ConvertOpacity(SourceBitmap, intOpacity, clrTransparentColor)
            If diwDrawImageWay = DrawImageWays.Tiled Then
                For Y = 0 To Device.ClientSize.Height Step SourceBitmap.Height
                    For X = 0 To Device.ClientSize.Width Step SourceBitmap.Width
                        ghpGraphics.DrawImage(SourceBitmap, X, Y)
                    Next
                Next
            ElseIf diwDrawImageWay = DrawImageWays.Stretch Then
                ghpGraphics.DrawImage(SourceBitmap, 0, 0, Device.ClientSize.Width, Device.ClientSize.Height)
            ElseIf diwDrawImageWay = DrawImageWays.Normal Then
                ghpGraphics.DrawImage(SourceBitmap, PosX, PosY)
            End If
            ghpGraphics.Dispose()
        End Sub

    i'm sorry my friend. i know programming and see very things... but these it's kill me:(

    Saturday, January 26, 2013 7:18 PM
  • Paul,

    In my perception Cabalinho did already what you wrote in your last message. 

    He placed his full class inside this thread, which shows much more elements which are useful to everybody who tries to make a color image Black and White like he wrote. 

    Therefore I hope a moderator will mark the by me proposed reply from him as answer.


    Success
    Cor

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:40 PM
    Saturday, January 26, 2013 7:22 PM
  • Paul,

    In my perception Cabalinho did already what you wrote in your last message. 

    He placed his full class inside this thread, which shows much more elements which are useful to everybody who tries to make a color image Black and White like he wrote. 

    Therefore I hope a moderator will mark the by me proposed reply from him as answer.


    Success
    Cor

    the function isn't mine;)

    but it's great;)

    Saturday, January 26, 2013 7:25 PM
  • Paul,

    In my perception Cabalinho did already what you wrote in your last message. 

    He placed his full class inside this thread, which shows much more elements which are useful to everybody who tries to make a color image Black and White like he wrote. 

    Therefore I hope a moderator will mark the by me proposed reply from him as answer.


    Success
    Cor

    Cor -

    I am speaking in reference to his original question, which where he changed the color of pixels by using GetPixel and SetPixel, one at a time, which I am sure you are well aware, is notoriously known for being slow. Not that GetPixel and SetPixel cannot accomplish the conversion, but just that it is a poor way of doing it.

    As far as a moderator marking the answer, sure and one will eventually, but isn't it better if he understands and is able to mark the answer to his own question?


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.

    Saturday, January 26, 2013 7:29 PM
  • ok... i'm confuse:(

    now works and i still don't understand that error:(

    and i'm sorry, but i still use my function.. at least, now i recive results;)

    why only me??????? only i get strange bugs:(

    Saturday, January 26, 2013 7:33 PM
  • ok... i found it;)

    i found the problem;)

    if i use these property:

    s.Transparent = CheckBox1.CheckState

    s.TransparentColor = PictureBox2.BackColor

    (i must use both... there is a bug here.. some here)

    Public Property TransparentColor() As Color
            Get
                ' Code to return the property’s value goes here.
                Return clrTransparentColor
            End Get
            Set(ByVal Value As Color)
                ' Code that accepts a new value goes here.
                clrTransparentColor = Value
            End Set
        End Property

        Public Property Transparent() As Boolean
            Get
                ' Code to return the property’s value goes here.
                Return blnTransparent
            End Get
            Set(ByVal Value As Boolean)
                ' Code that accepts a new value goes here.
                blnTransparent = Value
            End Set
        End Property

    if i don't use these 2 properties, the problems don't happen;)

    Saturday, January 26, 2013 7:41 PM
  • i have 1 question: the class have the Initializate event?

    i need something for changing the variables\properties before use something;)

    or i can use the AddBitmap() method to do the work;)

    Saturday, January 26, 2013 7:46 PM
  • Please check out this modified example for making your image transparent(from your project)

    Download link:

    Paul's Skydrive - graphicsex.zip

    Option Strict On
    Imports System.Runtime.InteropServices
    Imports System.Drawing.Imaging
    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim Source As Bitmap = CType(PictureBox1.Image, Bitmap)
            Dim NewBitMap As Bitmap = SwapColors(Source, Color.Transparent, Source.GetPixel(0, 0))
            Dim G As Graphics = Me.CreateGraphics
            G.DrawImage(NewBitMap, New Point(0, 0))
        End Sub
        Private Sub PictureBox1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
            Dim b As Bitmap
            b = New Bitmap(PictureBox1.Image)
            PictureBox2.BackColor = b.GetPixel(e.X, e.Y)
            b.Dispose()
        End Sub
        Private Function SwapColors(ByVal Source As Bitmap, ByVal NewColor As Color, ByVal OldColor As Color) As Bitmap
            If Not Source.PixelFormat = PixelFormat.Format32bppArgb Then
                Dim Converted As New Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb)
                Dim Graphics As Graphics = Graphics.FromImage(Converted)
                Graphics.DrawImage(Source, New Rectangle(0, 0, Source.Width, Source.Height), _
                                   0, 0, Source.Width, Source.Height, GraphicsUnit.Pixel)
                Source = Converted
            End If
            Dim rect As New Rectangle(0, 0, Source.Width, Source.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = Source.LockBits(rect, _
                Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat)
            Dim ptr As IntPtr = bmpData.Scan0
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * Source.Height
            Dim rgbValues(bytes - 1) As Byte
            Marshal.Copy(ptr, rgbValues, 0, bytes)
            Dim Blue, Green, Red, Alpha As Byte
            Dim CurrentPixel As Color
            For I = 0 To (bmpData.Stride * Source.Height) - 1 Step 4
                Blue = rgbValues(I)
                Green = rgbValues(I + 1)
                Red = rgbValues(I + 2)
                Alpha = rgbValues(I + 3)
                CurrentPixel = Color.FromArgb(Alpha, Red, Green, Blue)
                If CurrentPixel = OldColor Then
                    Alpha = NewColor.A
                    Red = NewColor.R
                    Green = NewColor.G
                    Blue = NewColor.B
                End If
                rgbValues(I) = Blue
                rgbValues(I + 1) = Green
                rgbValues(I + 2) = Red
                rgbValues(I + 3) = Alpha
            Next
            Marshal.Copy(rgbValues, 0, ptr, bytes)
            Source.UnlockBits(bmpData)
            Return Source
        End Function
    End Class
    


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 7:49 PM
  • thanks to all

    i use these method for iniciate all properties and now works fine:

    Public Sub AddBitmap(ByRef Source As Bitmap)
            SourceBitmap = New Bitmap(Source)
            clrBackColor = SourceBitmap.GetPixel(0, 0)
            clrOriginalBackColor = clrBackColor
            clrTransparentColor = clrBackColor
            blnTransparent = False
            blnBlackAndWhite = False
            intOpacity = 255
            diwDrawImageWay = DrawImageWays.Normal
            mrMirror = Mirrorr.None
            clrNewColor = clrBackColor
            clrOldColor = clrBackColor
            intRotate = 0
        End Sub

    thanks for all;)

    can 'Mark as Answer' for both?

    because both of you help me so much;)

    thanks

    • Marked as answer by Cambalinho Saturday, January 26, 2013 8:38 PM
    Saturday, January 26, 2013 7:57 PM

  • can 'Mark as Answer' for both?

    because both of you help me so much;)

    thanks

    You can mark any (multiple) answers that answered your question, and mark any posts you found helpful, the choice is yours.

    Well, I hope you didn't get confused by the bitmap.lockbits method, because this method performs so much better than GetPixel and SetPixel...

    If you have any questions about it, please let me know, and you're welcome.


    “If you want something you've never had, you need to do something you've never done.”

    Don't forget to mark helpful posts and answers ! Answer an interesting question? Write a new article about it! My Articles
    *This post does not reflect the opinion of Microsoft, or its employees.


    Saturday, January 26, 2013 7:59 PM
  • if you a have a nice tutorial.. please send me;)

    anotherthing: the class's don't have the Initializate event?

    the properties don't have a defauld\initializate values?

    Saturday, January 26, 2013 8:43 PM