C#使用画笔工具从外部重绘/重新创建图像

时间:2018-07-06 20:12:41

标签: c# drawing draw getpixel colormatrix

Phew,这里的首要任务是用简短的标题解释我要寻找的东西。

基本上,我想改进现有的像素绘制机器人。 主要目标:必须快速

我现在对它的性能相当满意,但是可以做得更好。简而言之,我所做的事情非常原始。总结一下:

  • 获取图像并将其处理为黑白(通过设置特定的ColorMatrix)
  • 遍历图像中的每个像素,并决定单击鼠标(如果它是黑色的话),然后单击(否则)。

我现在不确定(如何解决)我的主要(性能)问题:

  • 例如,我目前仍连续单击500次以在图像中绘制黑线,而不是单击一次并从x1拖动到x2
  • 使用System.Threading.Sleep(1):如果我不这样做,则目标应用程序将不会处理也不会绘制,除了几个像素(在MS Paint中进行测试)。我不应该使用异步异步等吗?我从没学过如何成功替换Sleep();
  • 我听说img.GetPixel(x,y)是一种缓慢的方法,应该替换为Bitmap.LockBits()吗?协议,问题吗?
  • 我正在通过user32.dll导入RegisterHotKey并重写WndProc以侦听全局系统热键(以开始绘制过程),这是否也可以使用本机C#元素更好地解决?我注意到有时在构建解决方案时或在调试时,它可能要花几秒钟的时间才能开始运行我的程序。

最后,最重要的是-codeZ:

绘图:

    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:

以下是有关我的第一个性能问题的a demonstration:是GIF格式:单击和拖动比逐像素单击的速度无限快(此测试仍使用GetPixel())。

编辑#2

-片段-

让我们暂时忘记LockBits()。

我主要关心的是:如何按行或理想情况下扫描每个像素的“质量”,所以我可以告诉我的程序:好的,here is this black and white image:我不希望您单击每个黑色像素连续数百次,但是我想要这样的逻辑:扫描->第一个黑色像素->按住鼠标->继续直到遇到白色像素->释放。冲洗并重复。

请选中“编辑1”,以了解为什么我相信这一点:更快地打印图像!

以下测试对我而言太慢了! SEE ANIMATED GIF

编辑#3:

I expect a nice rectangle but get zigzags

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

    }

我知道这是因为睡眠间隔短,如果增加睡眠间隔,我将得到我想要的结果:我怀疑如果要使其尽可能快地运行而不必尝试,则必须使用等待异步列出几个睡眠延迟的数字。

0 个答案:

没有答案