3

On a form I have a PictureBox, a button to load image in the picturebox and couple of more buttons to do some operations on the image loaded into the picturebox.

I load a bitmap image into the picturebox and then I want to perform some operation on pixel ranges rgb(150,150,150) to rgb(192,222,255) of the loaded image.

  • Is it possible to do this using SetPixel method?
  • Is there any way to specify a range of RGB values in C#?
Abel
  • 56,041
  • 24
  • 146
  • 247
  • 1
    Yes, you can use SetPixel, of course, but it is extremely slow. – Abel Jan 16 '12 at 17:56
  • What exactly do you mean by a "range"? If you imagine the RGB color space and the two points you have, do you want the whole cube between those two points or just a line? – svick Jan 16 '12 at 18:02
  • @svick: Actually I'm very new to image manipulation techniques. The thing is that the color is basically one (grey in this case, as perceived by the eye) but the rgb values are varying like (150,150,150),(163,163,163),(178,178,178) and so on. So, I wanted to perform some operations on the specified color. – OutOfBoundsException Jan 16 '12 at 18:20

3 Answers3

5

Simple way would be something like this:

for (int i = 0; i < width; i++)
   for (int j = 0; j < height; j++)
   {
       Color c = bitmap.GetPixel(i, j);
       if (ColorWithinRange(c))
       {
           // do stuff
       }
   }

With ColorWithinRange defined like this:

private readonly Color _from = Color.FromRgb(150, 150, 150);
private readonly Color _to = Color.FromRgb(192, 222, 255);
bool ColorWithinRange(Color c)
{
   return 
      (_from.R <= c.R && c.R <= _to.R) &&
      (_from.G <= c.G && c.G <= _to.G) &&
      (_from.B <= c.B && c.B <= _to.B);
}

For large bitmap sizes, however, GetPixel and SetPixel become very slow. So, after you have implemented your algorithm, if it feels slow, you can use the Bitmap.LockBits method to pin the bitmap (prevent GC from moving it around memory) and allow yourself fast unsafe access to individual bytes.

vgru
  • 49,838
  • 16
  • 120
  • 201
1

Loop through your picturebox ang use GetPixel to get your pixel, check if pixel rgb is in range and use SetPixel to modify pixel.

Emmanuel N
  • 7,350
  • 2
  • 26
  • 36
0

GetPixel / SetPixel approach (suggested in previous answers) should work correctly, BUT it's very slow, especially if you want to check every pixel in a large image.

If you want to use more efficient method, you can try to use unsafe code. It seems a little bit more complicated, but if you have worked with pointers before, it shouldn't be a problem. You can find some more information about this method in other questions on StackOverflow, like: Unsafe Per Pixel access, 30ms access for 1756000 pixels or find a color in an image in c#.

Community
  • 1
  • 1
Lukasz M
  • 5,635
  • 2
  • 22
  • 29