Question

I love SO. In 8 out of 10 questions it produces a straightforward and immediately usable answer. Or at least explains why my question is somehow wrong.

So I found it strange that I couldn't find an answer to my liking for this simple and, I had asumed, rather common question.

After searching high and low I patched together the below solution. It works alright but I wonder:

  • Are there flaws in it? (e.g.: do I need the dispose?)

  • Is there a better solution, maybe with less copying going on?

I'd like to see a soultion with CopyFromScreen , which potentially uses only a 1x1 bitmap size, but needs a Graphics.. So an alternative solution would be appreciated.

Or one that accesses the control's pixels directly.

Note 1: I want to grab the colors from a panel! Not from a picturebox and not from the screen.. Note 2: For my project speed is not important, as I want to create an eyedropper tool. But speedy ways are welcome, too; who knows where I'll go next ..

My solution:

public Color getColor(Control ctl, Point location)
{
   Bitmap bmp = new Bitmap(ctl.Width, ctl.Height);
   ctl.DrawToBitmap(bmp, new Rectangle(0, 0, ctl.Width, ctl.Height));
   Color col = bmp.GetPixel(location.X, location.Y);
   bmp.Dispose();
   return col;
}

I use it like this in the colorsPanel_MouseClick event:

       myPen = new Pen(getColor(colorsPanel, e.Location), myStrokeWidth);
Was it helpful?

Solution

I have come up with a version that uses CopyFromScreen like this:

public Color getScrColor(Control ctl, Point location)
{
   Bitmap bmp = new Bitmap(1, 1);
   Graphics g = Graphics.FromImage(bmp);
   Point screenP = ctl.PointToScreen(location);
   g.CopyFromScreen(screenP.X, screenP.Y, 0, 0, new Size(1, 1));
   Color col = bmp.GetPixel(0, 0);
   bmp.Dispose();
   return col;
}

It works fine, too but seems to be a lot slower (by a factor of 10) than the one that uses DrawToBitmap. I doubt that the PointToScreen is the reason and a test version, that hands over a Graphics without creating it each time was just as slow.

So I guess the CopyFromScreen call is so much slower, that the number of pixels is not important. Well, within reasonable limits, probably. My color palette Control is about 60x400 pixels.

So for the time being I guess the original GetColor solution is OK to use.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top