C# Перерисовать / воссоздать изображение снаружи с помощью кисти
Фу, первое бремя здесь, чтобы объяснить, что я ищу в коротком названии.
По сути, я хочу улучшить свой существующий бот для рисования пикселей. Основная цель: это должно быть быстро.
Я довольно доволен его производительностью, но он может быть лучше. То, что я делаю в двух словах, очень примитивно; подвести итог:
- Получите изображение и обработайте его, чтобы оно было черно-белым (путем установки определенного ColorMatrix)
- Прокрутите каждый пиксель изображения и решите щелкнуть мышью, если он черный, и пропустить, если нет.
Моя главная (производительность) касается сейчас, я не знаю, как решить:
- В настоящее время я все еще нажимаю 500 раз подряд для рисования черной линии на изображении, например, вместо того, чтобы щелкнуть и перетащить один раз с x1 на x2
- Использование System.Threading.Sleep(1): Если я этого не сделаю, целевое приложение не будет обрабатываться и не будет рисовать, за исключением нескольких пикселей (тестирование в MS Paint). Разве я не должен работать с асинхронным ожиданием и т.д.? Я так и не узнал, как успешно заменить Sleep();
- Я слышал, img.GetPixel(x, y) - медленный подход, и его следует заменить на Bitmap.LockBits()? Соглашения, проблемы?
- Я импортирую RegisterHotKey через user32.dll и переопределяю WndProc для прослушивания глобальной системной горячей клавиши (чтобы начать процесс рисования). Может ли это быть лучше решено с помощью собственных элементов C#? Иногда я замечаю, что при создании решения или при отладке требуется несколько секунд, пока моя программа не запустится изначально.
Наконец, самое главное - код Z:
Рисование:
void Draw()
{
Bitmap imgClipBoard = MakeBlackAndWhite((Bitmap)Clipboard.GetImage());
Point startPos = Cursor.Position;
ClickMouse(MouseButtons.Left, startPos.X, startPos.Y, true);
ClickMouse(MouseButtons.Left, startPos.X, startPos.Y, false);
for (int y = 0; y < img.Height; y++)
{
for (int x = 0; x < img.Width; x++)
{
Color c = img.GetPixel(x, y);
if (c.B == 0)
{
int drawX = startPos.X + x;
int drawY = startPos.Y + y;
MoveMouse(drawX, drawY);
ClickMouse(MouseButtons.Left, drawX, drawY, true);
ClickMouse(MouseButtons.Left, drawX, drawY, false);
Thread.Sleep(1);
}
if (Keyboard.IsKeyDown(Keys.Escape))
return;
}
}
}
Что мне также интересно: есть ли более разумные способы перерисовать изображение программно, чем попиксельное? Например, определение путей (линий) в изображении для отслеживания одним штрихом вместо зацикливания сверху вниз и щелчка пикселей, или это уже что-то очень продвинутое?
Редактировать № 1:
Вот демонстрация в формате GIF, касающаяся моей первой проблемы с производительностью: щелчок и перетаскивание бесконечно быстрее, чем нажатие пиксель за пикселем (этот тест все еще использует GetPixel()).
Редактировать № 2
- Снип -
Давайте пока забудем о LockBits ().
Моя главная задача заключается в следующем: как я могу сканировать каждый пиксель "массой", либо по линии, либо в идеале по всей картинке, чтобы я мог сказать своей программе: Хорошо, вот это черно-белое изображение: я не хочу, чтобы вы нажимали сотни Количество раз подряд для каждого черного пикселя, но вместо этого я хочу эту логику: сканирование -> первый черный пиксель -> удерживайте мышь -> продолжайте, пока вы не нажмете белый пиксель -> отпустить. Промыть и повторить.
Пожалуйста, проверьте Редактировать 1, чтобы понять, почему я считаю, что это имеет смысл: намного быстрее печать изображений!
Этот следующий тест слишком медленный для моих целей! Посмотреть анимированный GIF
Редактировать № 3:
Я ожидаю хорошего прямоугольника, но получаю зигзаги
private void DrawRect()
{
int x = Cursor.Position.X;
int y = Cursor.Position.Y;
for (int counter = 0; counter < 100; counter++)
{
MoveMouse(x, y + counter);
ClickMouse(MouseButtons.Left, x, y + counter, true);
Thread.Sleep(1);
MoveMouse(x + 100, y + counter);
Thread.Sleep(1);
}
Thread.Sleep(15);
ClickMouse(MouseButtons.Left, 0, 0, false);
}
Я знаю, что это из-за коротких интервалов сна, и если я увеличу их, я получу именно то, что хочу: я подозреваю, что мне придется использовать асинхронное ожидание, если я хочу, чтобы это работало как можно быстрее, без необходимости опробовать несколько чисел для задержки сна.