另一个图片框顶部的透明图片框不起作用。如何解决这个问题?

时间:2014-03-03 18:34:37

标签: c# winforms image paint picturebox

我想创建两个重叠的图片框。 第一个Picturebox用作背景,屏幕图片。 使用这种方法:

public void BckShow()
{
     Rectangle rect = Screen.GetBounds(this);
     gBackImg = Graphics.FromImage(bBackImg);
     gBackImg.CopyFromScreen(0,0,0,0,
               Screen.PrimaryScreen.Bounds.Size,
               CopyPixelOperation.SourceCopy);
}

第二个图片框位于第一个图片框上方,一个可以使用此鼠标事件绘制的透明图片框:

public void Draw(bool draw, Point sp, Point ep)
        {
            if (draw)
            {
                gCanvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                pen = new Pen(new SolidBrush(ColorName), BrushSize);
                if (toolPen.Checked)
                {
                    gCanvas.DrawLine(pen, sp, ep);
                }
                else if (toolEreser.Checked)
                {
                    Rectangle rect = new Rectangle(ep.X, ep.Y, BrushSize*5, BrushSize*5);
                    gCanvas.DrawEllipse(pen, rect);
                    gCanvas.FillEllipse(new SolidBrush(ColorName), rect);
                }
                bCanvas.MakeTransparent(Color.White);
                pbxCanvas.Refresh();
                dirty = true;
                toolSave.Enabled = true;
            }
        }

        private void pbxCanvas_MouseDown(object sender, MouseEventArgs e)
        {
            sp = e.Location;
            if (e.Button == MouseButtons.Left)
            {
                ActivePaint = true;
            }
        }

        private void pbxCanvas_MouseUp(object sender, MouseEventArgs e)
        {
            ActivePaint = false;
        }

        private void pbxCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            ep = e.Location;
            Draw(ActivePaint, sp, ep);
            sp = ep;
        }

但是当我运行程序时,第二个PictureBox在触发鼠标事件时不会绘制任何内容。我怎么能解决这个问题?

我这样做是因为我只想将图像保存在第二个图片框中。与PrintScreen不同,但似乎在屏幕上做笔记并将图像与屏幕图像区分开来。

还有其他办法吗?比如使用图片框以外的控件,或者可以直接使用屏幕作为背景,但仍然可以将图像分别保存在透明的PictureBox中。

这是我想要实现的例子:

绘图时: enter image description here

结果存储图像:

enter image description here

我希望你们都能帮助我解决这个问题。对不起解释不好。

这是文档大纲窗口的更多细节: enter image description here

2 个答案:

答案 0 :(得分:0)

你的表面很可能因刷新而过度拉长。您应该跟踪要绘制的内容,然后在图片框的Paint事件中绘制它。这样,你就会得到一个Graphics对象,每次刷新,你都在画画。

当然,假设您首先拥有一个有效且正确的Graphics对象。

BTW:将表单范围变量传递给Draw会让人感到困惑,只需使用它即可。

答案 1 :(得分:0)

检查你的gCanvas初始化程序,如果在Paint事件(e.Graphics)中使用它,那么当你调用Refresh()方法时你的更改就会丢失。 Refresh()会触发一个新的Paint事件,创建一个新的Graphics对象,从而使你的对象无效。 从PictureBox的图像创建一个新的图形对象,以永久保留您的更改。

private List<Point> points = new List<Point>();

private void pbxCanvas_MouseDown(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        ActivePaint = true;
    }
}

private void pbxCanvas_MouseUp(object sender, MouseEventArgs e) {
    ActivePaint = false;
    points.Clear();
}

private void pbxCanvas_MouseMove(object sender, MouseEventArgs e) {
    if (ActivePaint) {
        points.Add(e.Location);
        Refresh();
    }
}

private void pbxCanvas_Paint(object sender, PaintEventArgs e) {
    using (var graphics = Graphics.FromImage(pbxCanvas.Image)) {
        for (int i = 0; i < points.Count - 1; i++) {
            graphics.DrawLine(Pens.Black, points[i], points[i + 1]);
        }
    }
}