0

我已经编写了这段代码,但是它不起作用。这不仅行不通,而且我尝试过的绘图方法都没有奏效。我花了一两个多小时试图解决这个问题,但没有成功。我尝试过简单的程序,它所做的只是显示一条小线,但无论我做什么它都不会工作:c

我做错了什么,或者什么可能导致这种情况?

private void pictureBox1_MouseDown(object sender, 
                                   MouseEventArgs m, 
                                   EventArgs e, 
                                   PaintEventArgs q)
{
    if (m.Button == System.Windows.Forms.MouseButtons.Left)
    {
        Point currpoint = System.Windows.Forms.Cursor.Position;

        Point origin = new Point(0, 0);

        decimal sizee = nud.Value;

        int size = Convert.ToInt32(sizee);

        Random randonGen = new Random();

        Color randomColor = Color.FromArgb(randonGen.Next(255),
                                           randonGen.Next(255),
                                           randonGen.Next(255));

        Pen selPen = new Pen(randomColor, size);

        Graphics g = Graphics.FromImage(pictureBox1.Image);

        g.DrawLine(selPen, 3, 3, 133, 133);
    }
}
4

4 回答 4

4

尝试添加一个

pictureBox1.Invalidate();

称呼。

于 2012-06-18T22:32:30.260 回答
1

这不是绘制图片框的正确方法:

private void pictureBox1_MouseDown(object sender, 
                                   MouseEventArgs m, 
                                   EventArgs e, 
                                   PaintEventArgs q)
{
    if (m.Button == System.Windows.Forms.MouseButtons.Left)
    {
        Point currpoint = System.Windows.Forms.Cursor.Position;

        Point origin = new Point(0, 0);

        decimal sizee = nud.Value;

        int size = Convert.ToInt32(sizee);

        Random randonGen = new Random();

        Color randomColor = Color.FromArgb(randonGen.Next(255),
                                           randonGen.Next(255),
                                           randonGen.Next(255));

        Pen selPen = new Pen(randomColor, size);

        using(Graphics g = pictureBox1.CreateGraphics()) // Use the CreateGraphics method to create a graphic and draw on the picture box. Use using in order to free the graphics resources.
        {
             g.DrawLine(selPen, 3, 3, 133, 133);
        }
    }
}

顺便说一句,此方法将创建一个临时图像,该图像在控件无效时被重置。对于更持久的绘图,您需要监听图片框的 Paint 事件并在那里绘制您的图形。

于 2012-06-18T22:32:55.463 回答
0

您必须先从图像中绘制它。然后将其附加到pictureBox1

Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(canvas);

Point currpoint = System.Windows.Forms.Cursor.Position;

Point origin = new Point(0, 0);

decimal sizee = nud.Value;

int size = Convert.ToInt32(sizee);

Random randonGen = new Random();

Color randomColor = Color.FromArgb(randonGen.Next(255),
                                   randonGen.Next(255),
                                   randonGen.Next(255));

Pen selPen = new Pen(randomColor, size);

g.DrawLine(selPen, 3, 3, 133, 133);
pictureBox1.image = canvas;
于 2014-08-18T10:41:56.127 回答
0

这是一个老问题,如果其他人也有类似的问题。见下文。首先让我们检查一下 Ops 代码。

(1)查看代码:建议的第一个更改是保持 Pen 的格式简单,直到我们更好地了解 Pen 在绘制图形时的实际工作方式。看看我们从图像创建图形的 Op 行,这是一个很好的例子,说明如何通过使用位图的图形上下文直接绘制(“这意味着写入”)到提供的位图。接下来,Op 提供了一个很好的 Graphics DrawLine 方法示例,该方法可以将定义的线绘制到提供的位图上。

(2) 由于缺少细节,我们必须对 Op 提供的位图以及他们在位图上画线的方法做出以下假设。假设这个pictureBox1中已经存在一个图像;如果未设置图像,我们从图像获得的图形将来自空图像,或者每个像素将是黑色的,就像脚注一样:

(a) Pen 的颜色是否对现有位图是唯一的,并且颜色的 Alpha 分量是否足够高,可以在绘制时实际看到生成的颜色(如果有疑问,请使用唯一的纯色或至少将Alpha 通道设置为 255) ?

(b) Op 想要绘制的这条线从左3 开始,3 到133,即位图左侧右侧 3 像素,该线的高度为 133,因此笔的线大小已更改为演示目的,宽度 = 3。

(c) 最后的考虑,pictureBox1.Size是否足以让我们看到这条画线?线条的几何形状形成一个类似于 RectangleF(3, 3, 3, 133) 结构的矩形,因此如果 pictureBox1 Bounds 矩形与派生线条的矩形相交,则该相交的区域就是可以绘制线条并视为可见的区域。

在我们可以从图形绘制到 pictureBox1 图像之前,我们必须首先将 pictureBox1 图像数据转换回可用的图像类型,例如位图。原因是图片框仅以数组格式存储像素数据,如果不转换为图像类型,GDI/GDI+ 不能直接使用。bitamp,jpeg,png等。

如果您通过自定义用户控件和正确处理 PaintEventArgs OnPaint实现和/或通过使用相关的图形屏幕缓冲区上下文场景来处理自己的绘画,则可以避免这种混乱的转换。

对于那些只想知道缺少什么的人:

    private void button1_Click(Object sender, EventArgs e)
    {
        Pen selPen = new Pen(Color.Red, 2);  //  The Op uses random color which is not good idea for testing so we'll choose a solid color not on the existing bitmap and we'll confine our Pen's line size to 2 until we know what we're doing.

        //  Unfortionately the picture box "image" once loaded is not directly usable afterwords.

        //  We need tp recreate the pictureBox1 image to a usable form, being the "newBmp", and for efficiency the bitmap type is chosen
        Bitmap newBmp = new Bitmap(pictureBox1.Width, pictureBox1.Height, PixelFormat.Format32bppArgb); // Tip: Using System.Drawing.Imaging for pixel format which uses same pixel format as screen for speed

        // We create the graphics from our new and empty bitmap container
        Graphics g = Graphics.FromImage(newBmp);

        // Next we draw the pictureBox1 data array to our equivelent sized bitmap container
        g.DrawImage(pictureBox1.Image, 0, 0);

        g.DrawLine(selPen, 3, 3, 3, 133);  // Format: (pen, x1, y1, x2, y2)
        pictureBox1.Image = newBmp;

        //  Don't forget to dispose of no longer needed resources
        g.Dispose();
        selPen.Dispose();
        newBmp.Dispose(); // or save newBmp to file before dispose ie. newBmp.Save("yourfilepath", ImageFormat.Jpeg) or in whatever image type you disire;
    }

到目前为止,操作的代码只在位图表面画一条线,如果我们要“看到”这个变化,我们必须将位图保存到文件中以便稍后在图像查看器中查看,或者我们必须将更新的位图绘制到我们的显示监视器,屏幕。_

有几种方法可以绘制到显示器的屏幕上。可以使用的最常见的图形上下文是Control.CreateGraghics,从 ( PaintEventArgs ) 到屏幕的图形方​​法和/或使用有时称为并用作手动双缓冲图形上下文的图形屏幕缓冲区,其中所有内容都是通过以下方式实现的来自图形的DrawImage方法。

最简单的解决方案(在这种情况下基于 Op 自己的代码)是使用 pictureBox1 控件显示这个新更新的位图。我们将简单地使用新更新的位图更新控件的图像,当然,一旦第一次转换为使用图形图像,如上面的代码描述中所示。

快乐编码!

于 2018-06-25T18:19:08.090 回答