Click here to Skip to main content
15,888,461 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello
pictureBox1 has imge of lamp in the center with size of 100x100 pixel using
co = ((Bitmap)pictureBox1.Image).GetPixel(3, 3) which seems to be the back ground color
i want to change that color to NewColor but it did not work,i found all pixels color is white
R=255, G=255, B=255

What I have tried:

C#
Color NewColor = Color.FromArgb(1, 1, 155, 100);
Color co;
for (i = 0; i < wid; i++)
{
    for (j = 0; j < hig; j++)
    {
        co = ((Bitmap)pictureBox1.Image).GetPixel(i, j);
        if (co.R == 255 && co.G == 255 && co.B == 255)
        {
             ((Bitmap)pictureBox1.Image).SetPixel(i, j,NewColor);
        }
    }//for j
 }//for i
Posted
Updated 29-Mar-24 22:49pm
v2

When you modify an image loaded directly from a file or resource, you need to create a new Bitmap object and make changes to that new object, apply your changes, and then assign the modified Bitmap back to your 'PictureBox.Image' property -

C#
int picwidth = pictureBox1.Image.Width;
int picheight = pictureBox1.Image.Height;
Bitmap bmp = new Bitmap(pictureBox1.Image);
Color NewColor = Color.FromArgb(1, 1, 155, 100);

for (int i = 0; i < picwidth ; i++)
{
    for (int j = 0; j < picheight ; j++)
    {
        Color co = bmp.GetPixel(i, j);
        if (co.R == 255 && co.G == 255 && co.B == 255)
        {
            bmp.SetPixel(i, j, NewColor);
        }
    }
}

pictureBox1.Image = bmp;


You can also see - Replace color in an image in C#[^]
 
Share this answer
 
v4
If I try your code with one of my own images and add a counter and supporting code:
C#
Color NewColor = Color.FromArgb(1, 1, 155, 100);
Color co;
int wid = pictureBox1.Width;
int hig = pictureBox1.Height;
int cnt = 0;
for (i = 0; i < wid; i++)
    {
    for (j = 0; j < hig; j++)
        {
        co = ((Bitmap)pictureBox1.Image).GetPixel(i, j);
        if (co.R == 255 && co.G == 255 && co.B == 255)
            {
            ((Bitmap)pictureBox1.Image).SetPixel(i, j, NewColor);
            cnt++;
            }
        }//for j
    }//for i
Then I get what I expected: unnoticeable changes to the image because the counter ends up as 3 - indicating only three white pixels were found in the whole image.
Given that the image was of a black and white cat in a garden that's about what I would expect to get - very little in a photo is ever "pure white": at least one of the R G or B parts will be at least one smaller!

Indeed, if I change the code so it only compares the red portion with 255 the counter only rises to 60!

Use the debugger and check what exactly is happening: I think you will find there is almost no matches in your image.

I'd also change your code to make it more readable:
C#
Color newColor = Color.FromArgb(1, 1, 155, 100);
Bitmap picture = (Bitmap) pictureBox1.Image;
int cnt = 0;
for (int i = 0; i < picture.Width; i++)
    {
    for (int j = 0; j < picture.Height; j++)
        {
        Color co = picture.GetPixel(i, j);
        if (co.R == 255 && co.G == 255 && co.B == 255)
            {
            picture.SetPixel(i, j, newColor);
            cnt++;
            }
        }
    }
 
Share this answer
 
Comments
Andre Oosthuizen 30-Mar-24 5:00am    
Lol, sorry Paul, came through at the same time...
OriginalGriff 30-Mar-24 5:35am    
Not a problem - happens all the time.
Where did you get the "changing bitmaps causes problems" idea from? It's a perfectly valid thing to do, and I've done it for over a decade without having to create a new bitmap. The only time I can see it might cause a problem is if it's created from a file (via Bitmap.FromFile / Image.FromFile) because they lock the original file until the Image is Disposed.
I've never had a problem editing a Bitmap (though I don't normally use GetPixel / SetPixel as they are phenomenally inefficient) so I'm wondering if I've just been lucky all these years! :laugh:
Andre Oosthuizen 30-Mar-24 5:44am    
I agree 100% if we are working with small items as is teh case here 100x100 and only 1 box with only 1 interaction. From the way I understand this, when you load an image into a PictureBox or create a Bitmap from an image file, the image data is typically loaded into an unmanaged memory area, and the Bitmap object acts as a managed wrapper around that unmanaged memory, at least until it is released.
You might run into problems when you try to modify the unmanaged memory directly using the 'Bitmap.SetPixel' method as it is not thread-safe, leading to issues if multiple threads try to access or modify the same image data simultaneously. Maybe I'm just over-cautious. :) I have edited my post.
OriginalGriff 30-Mar-24 5:58am    
Ah, that makes sense - I normally handle thread safety myself when I need it, so it's not been a problem.
Yes, .Net images are handled by unmanaged code in GDIPlus.dll (which is why GetPixel and SetPixel are so spectacularly inefficient - P/Invoke for every call :shudder:)
You can use LockBits to get an IntPtr then use that to get a byte[] (or a pointer if you fancy going unsafe) and use multiple threads on that, subject to the usual caveats and cautions!
Andre Oosthuizen 30-Mar-24 6:11am    
LOL, and so you just reminded me again why I am staying away from anything graphics related. I went for it big time when I used VB6 as it was the "in-thing" at the time, nowadays I just find a solution elsewhere if I really need it, I rather stick to the boring old "1+1=2" interfaces. :) I suppose that's why your solution makes more sense than mine, maybe still based on old tech ways.
To add to the excellent answers here. In order to learn about working with images in C#, you should check out Christian Graus' articles on image processing in C#. The first one is Image Processing for Dummies with C# and GDI+ Part 1 - Per Pixel Filters[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900