none
QUestion about the FromARGB command RRS feed

  • Question

  • Hi I spent a lot of time trying to search how to use this command and I have yet to understand it.

    If I have

    DrawEllipse(Pens.Black, 10, 10, 10, 10) and I want to make my own color I cant seem to be able to do it.  I understand that you can refer to a color using RGB or there was mention that you can use a single number which takes all 3 colors into consideration??  From what I have read you cant just color a pixel/point but must use an ellipse ??  In either case I am trying to read a color on in picturebox1 and then at the same inside of picturebox2 want to set the pixel to match the same color of the pixel from picturebox1?  The few articles I read never seem to mention the graphis declaration you must have to work with the various commands.

    Any help would be appreciated,

    Les

    DrawEllipse(Pens.Black, 10, 10, 10, 10)

    Wednesday, December 6, 2017 5:49 AM

Answers

  • If I understand your question I set the image property in the picturebox to a bitmap picture.

     Do you mean that you created two new instances of a Bitmap that you have assigned to the PictureBox.Image property in your code?  If you are going to be working with the images or processing them in any way in your code,  i would suggest creating new instances of the Bitmap class for the images and using the Lockbits method i mentioned in my last post.

     For example,  i used the GetImageArgbBytes function from my example in the last link i gave you in my last post which uses the Bitmap.LockBits Method to get two Byte arrays of the color data,  one from each image.  Then i used the SequenceEqual extension method to return True or False to indicate if the two arrays are the same (images are the same).

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

    Public Class Form1 Private bm1 As Bitmap = Nothing Private bm2 As Bitmap = Nothing Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load bm1 = New Bitmap("C:\TestFolder\AngryBird.png") bm2 = New Bitmap("C:\TestFolder\AngryBird - Copy.png") 'AngryBird (changed).png PictureBox1.Image = bm1 PictureBox2.Image = bm2 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim same As Boolean = AreImagesSame(bm1, bm2) 'get a boolean value of True or False that indicates if the 2 Bitmap images are the same MessageBox.Show("Are Images The Same: " & same.ToString) End Sub Private Function AreImagesSame(b1 As Bitmap, b2 As Bitmap) As Boolean If b1.Size <> b2.Size Then Return False Return GetImageArgbBytes(b1).SequenceEqual(GetImageArgbBytes(b2)) End Function Private Function GetImageArgbBytes(b As Bitmap) As Byte() Dim bmd As BitmapData = b.LockBits(New Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb) Dim bts((bmd.Stride * bmd.Height) - 1) As Byte Marshal.Copy(bmd.Scan0, bts, 0, bts.Length) b.UnlockBits(bmd) Return bts End Function End Class

     

     

     

     You should be aware though,  that .jpg images use an encoder that will not always produce the same exact colors for each pixel in an image.  So,  you could have 2 images that appear exactly the same but,  will not match because some pixels are a slightly different shade of a color.

     This will also happen when a single image is saved in different image formats too.  For example,  the same image saved as two formats like,  one saved as a .png and one saved as a .gif or .jpg file will usually contain slightly different shades of colors.

     So,  there is not a 100% reliable way to detect if two .jpg files or 2 images of different formats are the same.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Friday, December 8, 2017 8:34 PM Forgot to show the Imported namespaces in the code
    • Marked as answer by Les2011 Friday, December 15, 2017 4:27 AM
    Friday, December 8, 2017 5:17 PM

All replies

  • Use Pens with the Draw commands. Use Solidbrushes with Fill commands. Both Pens and SolidBrushes need the Color property. See this for an example: -

        Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            Dim I, J As Integer
            Dim pnn As New Pen(Color.FromArgb(40, 40, 40))
            Dim cl As Color
            pnn.Width = 2
            For I = 1 To 481 Step 30
                e.Graphics.DrawLine(pnn, I, 0, I, 481)
                e.Graphics.DrawLine(pnn, 0, I, 481, I)
            Next
            For I = 0 To 15
                For J = 0 To 15
                    cl = bmp.GetPixel(I, J)
                    e.Graphics.FillRectangle(New SolidBrush(cl), I * 30 + 1, J * 30 + 1, 28, 28)
                Next
            Next
        End Sub

    When working with single pixels, it may be worth reading up on SetPixel and GetPixel. Use the MSDN library for more information, but you are welcome to ask specific questions and ask for simple examples from this forum.


    Burn all valuable data to CD/DVD disks. EMP proof.


    • Edited by LeonCS Wednesday, December 6, 2017 8:12 AM
    Wednesday, December 6, 2017 8:09 AM
  • In either case I am trying to read a color on in picturebox1 and then at the same inside of picturebox2 want to set the pixel to match the same color of the pixel from picturebox1?

    A PictureBox is a control, and you can't work with it like that.  You have to work with an image, such as a bitmap. 
    https://msdn.microsoft.com/en-us/library/system.drawing.bitmap(v=vs.110).aspx

    The bitmap supports some simple methods such as GetPixel and SetPixel, but to work with more advanced features such as ellipses you will need a graphics object:
    https://msdn.microsoft.com/en-us/library/system.drawing.graphics(v=vs.110).aspx

    When the bitmap has been created or adjusted as required, then you can use the Picturebox Image property to display it (although there are other ways that you can display a bitmap).
    https://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox.image(v=vs.110).aspx

    Wednesday, December 6, 2017 8:36 AM
  • That depends in most windows forms controls. (FromArgb is a windows drawing method which uses that Drawing Namespace). You can set the colors of most controls.

    For instance 

    Keep in mind that it is a method from a namespace, not a kind of VB feature. In WPF for instance it is afaik not available in the color class. (You can convert a drawingcolor to WPF then.)

     

    Success
    Cor


    • Edited by Cor Ligthert Wednesday, December 6, 2017 9:44 AM
    Wednesday, December 6, 2017 9:44 AM
  • Please note:  If all 3 RGB values are identical, you will get varying shades of gray ranging from black (0,0,0) to white (255,255,255).

    Solitaire

    Wednesday, December 6, 2017 9:10 PM
  •  If you could explain with a little more detail what the end goal for doing this is,  there may be other ways of doing it or maybe better methods than using the Bitmap class's GetPixel and SetPixel methods which can be slow for processing larger images.  Do you want to make a copy of an existing image,  or maybe overlay one image onto another,  or something else?

    If you say it can`t be done then i`ll try it

    Wednesday, December 6, 2017 9:11 PM
  • Hi IR,

    Thx for your response.  What I really want to do, don't care if it takes time as much as it working right.  I have an image in a picturebox1 and want to grab the color of each pixel and compare it to the pixels that correspond to the same  x,y coordinate in another picturebox2.  Any difference would tell me the picture is no longer the same.  So I need to be able to read each pixel in picturebox1 and see if it differs to the same pixel in picturebox2.  Also IR is there a way of just setting or drawing to an actual pixel??  From some reading I have done it says that your best to use an ellipse??  Can I just work with pixels?

    Thanks IR in advance

    Les

    Wednesday, December 6, 2017 11:29 PM
  • Hi IR,

    Thx for your response.  What I really want to do, don't care if it takes time as much as it working right.  I have an image in a picturebox1 and want to grab the color of each pixel and compare it to the pixels that correspond to the same  x,y coordinate in another picturebox2.  Any difference would tell me the picture is no longer the same.  So I need to be able to read each pixel in picturebox1 and see if it differs to the same pixel in picturebox2.  Also IR is there a way of just setting or drawing to an actual pixel??  From some reading I have done it says that your best to use an ellipse??  Can I just work with pixels?

    Thanks IR in advance

    Les

     Ok,  i understand what you are doing now.  What is suppose to happen if a pixel color has changed?  Is this just to indicate that the images are different,  or maybe you want to set the pixel color back to the color of the original image,  or maybe even store changed pixel indexes or (x,y) positions for later use?

     You could draw an ellipse that is a size of (1x1) if you really wanted i suppose but, i am not so sure you need to do that at this point.  As long as you have your two Bitmap images you can compare the pixels two ways,  one which way is using the Bitmap.GetPixel Method and Bitmap.SetPixel Method with two loops to iterate through the x and y locations of each pixel.

      If you are working with any larger images,  like 800x600 or larger,  the Bitmap.LockBits Method is much faster but,  a little trickier to work with.  I have shown an example at the link below that is probably close to what you want to do.  It is the 4th post up from the bottom.  It compares the pixels of two Bitmap images and creates a new Bitmap image of just the pixels that have changed.  With a little work,  i am sure it would do just what you want.

    How to "add" two images so that resulting is the difference of the two


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Thursday, December 7, 2017 2:04 AM
    Thursday, December 7, 2017 1:48 AM
  • So I need to be able to read each pixel in picturebox1 and see if it differs to the same pixel in picturebox2.

    You can't do that with a picturebox.  You can only do it with an image (such as a bitmap).   How did you get the picturebox to display that picture?  That's the code you need to look at to find the image that you are trying to manipulate.

    Thursday, December 7, 2017 1:53 AM
  • Hi Acamar

    If I understand your question I set the image property in the picturebox to a bitmap picture.

    Friday, December 8, 2017 5:51 AM
  • If I understand your question I set the image property in the picturebox to a bitmap picture.

    Is that what you are doing, or are you stating what you need to do?

    If you have a bitmap object for the source and you have a bitmap object for the destination, then you can use GetPixel to get a pixel from some location in the source bitmap, and SetPixel to set the pixel at some (the same?) location in the destination.  GetPixel returns a color, and SetPixel requires a color.   There is no need to know what the color is, or to convert to/from an ARGB.  I can't see that there is any need to make your own color.  You should indicate exactly what part of the process you are having a problem with.

    Friday, December 8, 2017 7:08 AM
  • I am sorry Acamar for not explaining it well enough.  Basically I want to have 2 images.  All I want to do is look at each individual pixel from image 1 and compare that same pixel in image 2.  If they are the same I want to continue and if they are different I want to stop.  Hopefully I have cleared it up but if its still not clear let me know.  Sorry for the confusion.

    THx

    Les

    Friday, December 8, 2017 7:50 AM
  • So in fact you don't care about the color but want to know if there are differences in the byte array. 

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim byteArray1, byteArray2 As Byte()
            Using fo As New OpenFileDialog With {.Filter = "JpG (*.jpg)|*.jpg|Gif (*.gif)|*.gif|All files (*.*)|*.*"}
                If fo.ShowDialog = DialogResult.OK Then
                    Dim fs As New IO.FileStream(fo.FileName,
                   IO.FileMode.Open)
                    Dim br As New IO.BinaryReader(fs)
                    byteArray1 = br.ReadBytes(CInt(fs.Length))
                    br.Close()
                    'just to show the sample without a fileread error
                    Dim ms As New IO.MemoryStream(byteArray1)
                    Me.PictureBox1.Image = Image.FromStream(ms)
                End If
                If fo.ShowDialog = DialogResult.OK Then
                    Dim fs As New IO.FileStream(fo.FileName,
                       IO.FileMode.Open)
                    Dim br As New IO.BinaryReader(fs)
                    byteArray2 = br.ReadBytes(CInt(fs.Length))
                    br.Close()
                    'just to show the sample without a fileread error
                    Dim ms As New IO.MemoryStream(byteArray2)
                    Me.PictureBox2.Image = Image.FromStream(ms)
                End If
            End Using
            For i = 0 To byteArray1.Length - 1
                If byteArray1(i) <> byteArray2(i) Then
                    MessageBox.Show("The images are not the same"
                        Return
                End If
            Next
        End Sub

    Don't look at the warnings you get, because those are not true bit simply something the compiler cannot recognize. 


    Success
    Cor

    Friday, December 8, 2017 8:42 AM
  • All I want to do is look at each individual pixel from image 1 and compare that same pixel in image 2.  If they are the same I want to continue and if they are different I want to stop.

    You should start by comparing the width and height properties - if these don't match the images cannot be the same.

    Then instead of a Getpixel and a SetPixel you need to use a GetPixel with each image.  Then you can compare the two colors returned.  You will do that by iterating over the rows and columns of pixels in the image, getting the corresponding pixel values as a color.  If you get to the end of the image and there has not been a difference, they must be the same.

    To compare colors you should use the ToArgb method.  That returns a 32-bit integer which can be compared directly.

    However, GetPixel is an extremely inefficient way to compare two images.

    Friday, December 8, 2017 9:05 AM
  • If I understand your question I set the image property in the picturebox to a bitmap picture.

     Do you mean that you created two new instances of a Bitmap that you have assigned to the PictureBox.Image property in your code?  If you are going to be working with the images or processing them in any way in your code,  i would suggest creating new instances of the Bitmap class for the images and using the Lockbits method i mentioned in my last post.

     For example,  i used the GetImageArgbBytes function from my example in the last link i gave you in my last post which uses the Bitmap.LockBits Method to get two Byte arrays of the color data,  one from each image.  Then i used the SequenceEqual extension method to return True or False to indicate if the two arrays are the same (images are the same).

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

    Public Class Form1 Private bm1 As Bitmap = Nothing Private bm2 As Bitmap = Nothing Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load bm1 = New Bitmap("C:\TestFolder\AngryBird.png") bm2 = New Bitmap("C:\TestFolder\AngryBird - Copy.png") 'AngryBird (changed).png PictureBox1.Image = bm1 PictureBox2.Image = bm2 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim same As Boolean = AreImagesSame(bm1, bm2) 'get a boolean value of True or False that indicates if the 2 Bitmap images are the same MessageBox.Show("Are Images The Same: " & same.ToString) End Sub Private Function AreImagesSame(b1 As Bitmap, b2 As Bitmap) As Boolean If b1.Size <> b2.Size Then Return False Return GetImageArgbBytes(b1).SequenceEqual(GetImageArgbBytes(b2)) End Function Private Function GetImageArgbBytes(b As Bitmap) As Byte() Dim bmd As BitmapData = b.LockBits(New Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb) Dim bts((bmd.Stride * bmd.Height) - 1) As Byte Marshal.Copy(bmd.Scan0, bts, 0, bts.Length) b.UnlockBits(bmd) Return bts End Function End Class

     

     

     

     You should be aware though,  that .jpg images use an encoder that will not always produce the same exact colors for each pixel in an image.  So,  you could have 2 images that appear exactly the same but,  will not match because some pixels are a slightly different shade of a color.

     This will also happen when a single image is saved in different image formats too.  For example,  the same image saved as two formats like,  one saved as a .png and one saved as a .gif or .jpg file will usually contain slightly different shades of colors.

     So,  there is not a 100% reliable way to detect if two .jpg files or 2 images of different formats are the same.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Friday, December 8, 2017 8:34 PM Forgot to show the Imported namespaces in the code
    • Marked as answer by Les2011 Friday, December 15, 2017 4:27 AM
    Friday, December 8, 2017 5:17 PM
  • Hi IR yes I do understand that but I will make sure they are a bmp format, I think that avoids the problem or for that matter I will work with whatever format that is reliable.  I plan on looking at the suggestions here this weekend.

    Thx again

    Les

    Friday, December 8, 2017 5:35 PM
  • Hi Acamar,

    Yes I agaree with you and thats why initially I thought I would probably have to use the ToArgb, I have to read up on it <S>.  I plan on playing with the suggestions here over the weekend.

    Thx Les

    Friday, December 8, 2017 5:38 PM
  • Hi Cor,

    I am not sure what is meant by the byte array?  I want to make sure that each pixel in one image is the same as that pixel in another image of a picture that appears to be the same by eye.

    I am planning on looking at all these suggestions over the weekend and will post my results.

    Thx

    Friday, December 8, 2017 5:40 PM
  • Hi IR yes I do understand that but I will make sure they are a bmp format, I think that avoids the problem or for that matter I will work with whatever format that is reliable.  I plan on looking at the suggestions here this weekend.

    Thx again

    Les


     The Png image format is a good all-around choice,  especially if you may have images to compare which contain transparent areas in the images.  Png is a lossless image format and it usually has a considerably smaller file size than a Bmp image. It is a 32bppArgb type which includes the Alpha channel as well as the Red, Green, and Blue channels.  This is the format which i lock the image data in memory as in my example no matter what type/format of images are loaded into the Bitmaps.     8) 

    If you say it can`t be done then i`ll try it

    Friday, December 8, 2017 6:16 PM