创建,绘制线条和保存位图会产生通用GDI +错误

时间:2015-10-14 21:34:04

标签: c# image winforms bitmap

我有一个非常简单的方法,它将签名作为点列表并将它们绘制为位图上的线条。我想将该位图保存到文件中,但是当我调用Save方法时,我得到了#34; GDI +中出现了一般错误"并且没有内在例外。

这看起来很简单,所以我不确定问题是什么。

using (var b = new Bitmap(width, height))
{
    var g = Graphics.FromImage(b);
    var lastPoint = points[0];
    for (int i = 1; i < points.Length; i++)
    {
        var p = points[i];
        // When the user takes the pen off the device, X/Y is set to -1
        if ((lastPoint.X >= 0 || lastPoint.Y >= 0) && (p.X >= 0 || p.Y >= 0))
            g.DrawLine(Pens.Black, lastPoint.X, lastPoint.Y, p.X, p.Y);
        lastPoint = p;
    }
    g.Flush();
    pictureBox.Image = b;
    b.Save("C:\\test.bmp");
}

我尝试使用所有可能的ImageFormats进行保存,将图形对象放在using语句中,作为一个远景我甚至尝试过:

using (var ms = new MemoryStream())
{
    b.Save(ms, ImageFormats.Bmp); // And b.Save(ms, ImageFormats.MemoryBmp);
    Image.FromStream(ms).Save("C:\\test.bmp");
}

奇怪的是,如果我删除b.Save(或忽略异常),pictureBox会完美地显示图像。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我会使用PictureBox事件中相应的Graphics绘制到Paint,然后保存到位图:

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        MyDrawing(e.Graphics);

        Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);
        pictureBox1.DrawToBitmap(b, pictureBox1.ClientRectangle);
        b.Save(@"C:\test.bmp");

    }
    private void MyDrawing(Graphics g)
    {
        var lastPoint = points[0];

        for (int i = 1; i < points.Count; i++)
        {
            var p = points[i];
            // When the user takes the pen off the device, X/Y is set to -1
            if ((lastPoint.X >= 0 || lastPoint.Y >= 0) && (p.X >= 0 || p.Y >= 0))
                g.DrawLine(Pens.Black, lastPoint.X, lastPoint.Y, p.X, p.Y);
            lastPoint = p;
        }
        g.Flush();
    }

enter image description here

保存的BMP:

enter image description here

答案 1 :(得分:1)

您的代码有两个问题,一个隐藏另一个:

  • 您的应用程序可能没有C:根目录的书面权限,因此Save失败。
  • 您也无法PictureBox显示Bitmap,然后在using区块中销毁该文件。

所以你应该把代码改成这样的东西:

var b = new Bitmap(width, height);

using (Graphics g = Graphics.FromImage(b))
{
    var lastPoint = points[0];
    for (int i = 1; i < points.Length; i++)
    {
        var p = points[i];
        // When the user takes the pen off the device, X/Y is set to -1
        if ((lastPoint.X >= 0 || lastPoint.Y >= 0) && (p.X >= 0 || p.Y >= 0))
            g.DrawLine(Pens.Black, lastPoint.X, lastPoint.Y, p.X, p.Y);
        lastPoint = p;
    }
    // g.Flush(); not necessary
    pictureBox1.Image = b;
    b.Save("C:\\temp\\test.bmp");
}

您还应该检查数组的Length,并考虑使用List<Points>,同时检查其Count并使用DrawLines points.ToArray()为了更好的线连接,特别是厚厚的半透明线!