Как я могу получить цвет пикселя панели в месте расположения мыши (RFC)

Я люблю ТАКОЕ. На 8 из 10 вопросов он дает прямой и сразу используемый ответ. Или, по крайней мере, объясняет, почему мой вопрос как-то неверен.

Поэтому мне показалось странным, что я не смог найти ответа на этот простой и, как я полагал, довольно распространенный вопрос.

После поиска вверху и внизу я исправил приведенное ниже решение. Это работает хорошо, но мне интересно:

  • Есть ли в нем недостатки? (например: мне нужно избавиться?)

  • Есть ли лучшее решение, возможно, с меньшим копированием?

Я хотел бы увидеть решение с CopyFromScreen , которое потенциально использует только размер растрового изображения 1x1, но нуждается в графике. Поэтому альтернативное решение будет оценено.

Или тот, который напрямую обращается к пикселям элемента управления.

Примечание 1: я хочу получить цвета с панели! Не с картинки и не с экрана.. Примечание 2: Для моего проекта скорость не важна, так как я хочу создать пипетку. Но приветствуются и быстрые пути; кто знает куда я пойду дальше..

Мое решение:

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;
}

Я использую это так в событии colorsPanel_MouseClick:

       myPen = new Pen(getColor(colorsPanel, e.Location), myStrokeWidth);

person TaW    schedule 18.03.2014    source источник


Ответы (1)


Я придумал версию, которая использует CopyFromScreen следующим образом:

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;
}

Он тоже работает нормально, но кажется намного медленнее (в 10 раз), чем тот, который использует DrawToBitmap. Я сомневаюсь, что PointToScreen является причиной, и тестовая версия, которая передает графику без ее создания каждый раз, была такой же медленной.

Поэтому я предполагаю, что вызов CopyFromScreen настолько медленнее, что количество пикселей не имеет значения. Ну, в разумных пределах, наверное. Моя цветовая палитра Control составляет около 60x400 пикселей.

Так что на данный момент я думаю, что исходное решение GetColor можно использовать.

person TaW    schedule 19.03.2014