Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保存Winforms面板';将图形内容添加到文件中?_C#_Winforms - Fatal编程技术网

C# 如何保存Winforms面板';将图形内容添加到文件中?

C# 如何保存Winforms面板';将图形内容添加到文件中?,c#,winforms,C#,Winforms,我制作了一个绘图程序,绘图内容(来自System.drawing)绘制在面板上。我尝试了这个方法来做一个简单的保存,现在,我只得到一个空白图像 我的位图有其属性。RawData为0。我不知道这是否重要 当我隐藏屏幕并再次显示时,面板将变为空白 另一方面,当我调用面板的pnlpoint.Refresh()时,面板变为空白。这幅画丢了。这是一个双缓冲区的东西,就像它不保留值一样 private bool Save() { Bitmap bmpDrawing;

我制作了一个绘图程序,绘图内容(来自System.drawing)绘制在面板上。我尝试了这个方法来做一个简单的保存,现在,我只得到一个空白图像

我的位图有其属性。RawData为0。我不知道这是否重要

当我隐藏屏幕并再次显示时,面板将变为空白

另一方面,当我调用面板的pnlpoint.Refresh()时,面板变为空白。这幅画丢了。这是一个双缓冲区的东西,就像它不保留值一样

   private bool Save()
    {
        Bitmap bmpDrawing; 
        Rectangle rectBounds;

        try
        { 
            // Create bitmap for paint storage
            bmpDrawing = new Bitmap(pnlPaint.Width, pnlPaint.Height);

            // Set the bounds of the bitmap
            rectBounds = new Rectangle(0, 0, bmpDrawing.Width, bmpDrawing.Height);

            // Move drawing to bitmap
            pnlPaint.DrawToBitmap(bmpDrawing, rectBounds);

            // Save the bitmap to file
            bmpDrawing.Save("a.bmp", ImageFormat.Bmp);
        }
        catch (Exception e)
        {
            MessageBox.Show("Error on saving. Message: " + e.Message);
        }

        return true;
    }

我会跳过使用面板,它不像ImageBox那样是为图形设计的-继续使用它,然后您可以轻松保存内容

更新
图片盒。我已经有一段时间没有使用WinForms了:D

这是一个最小的涂鸦程序,可以让你画持久线:

List<Point> curPoints = new List<Point>();
List<List<Point>> allPoints = new List<List<Point>>();

private void pnlPaint_MouseDown(object sender, MouseEventArgs e)
{
    if (curPoints.Count > 1)
    {
        // begin fresh line or curve
        curPoints.Clear();
        // startpoint
        curPoints.Add(e.Location);
    }
}

private void pnlPaint_MouseUp(object sender, MouseEventArgs e)
{
    if (curPoints.Count > 1)
    {
        // ToList creates a copy
        allPoints.Add(curPoints.ToList());
        curPoints.Clear();
    }
}

private void pnlPaint_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;
    // here we should check if the distance is more than a minimum!
    curPoints.Add(e.Location);
    // let it show
    pnlPaint.Invalidate();
}

private void pnlPaint_Paint(object sender, PaintEventArgs e)
{
    // here you can use DrawLines or DrawCurve
    // current line
    if (curPoints.Count > 1) e.Graphics.DrawCurve(Pens.Red, curPoints.ToArray());
    // other lines or curves
    foreach (List<Point> points in allPoints)
        if (points.Count > 1) e.Graphics.DrawCurve(Pens.Red, points.ToArray());
}

private void btn_undo_Click(object sender, EventArgs e)
{
    if (allPoints.Count > 1)
    {
        allPoints.RemoveAt(allPoints.Count - 1);
        pnlPaint.Invalidate();
    }
}

private void btn_save_Click(object sender, EventArgs e)
{
    string fileName = @"d:\test.bmp";
    Bitmap bmp = new Bitmap(pnlPaint.ClientSize.Width, pnlPaint.ClientSize.Width);
    pnlPaint.DrawToBitmap(bmp, pnlPaint.ClientRectangle);
    bmp.Save(fileName, ImageFormat.Bmp);
}
List curPoints=new List();
列出所有点=新建列表();
私有void pnlpoint_MouseDown(对象发送方,MouseEventArgs e)
{
如果(curPoints.Count>1)
{
//重新开始直线或曲线
curPoints.Clear();
//起点
宵禁点。添加(如位置);
}
}
私有void pnlPaint_MouseUp(对象发送方,MouseEventArgs e)
{
如果(curPoints.Count>1)
{
//托利斯特创建了一个副本
allPoints.Add(curPoints.ToList());
curPoints.Clear();
}
}
私有void pnlpoint_MouseMove(对象发送方,MouseEventArgs e)
{
如果(e.Button!=MouseButtons.Left)返回;
//在这里,我们应该检查距离是否超过最小值!
宵禁点。添加(如位置);
//让它表现出来
pnlpoint.Invalidate();
}
私有void pnlPaint_Paint(对象发送方,PaintEventArgs e)
{
//在这里,您可以使用DrawLines或DrawCurve
//当前线路
如果(curPoints.Count>1)e.Graphics.DrawCurve(Pens.Red,curPoints.ToArray());
//其他直线或曲线
foreach(列出所有点中的点)
如果(points.Count>1)e.Graphics.DrawCurve(Pens.Red,points.ToArray());
}
私有无效btn\u撤消\u单击(对象发送方,事件参数e)
{
如果(allPoints.Count>1)
{
allPoints.RemoveAt(allPoints.Count-1);
pnlpoint.Invalidate();
}
}
私有无效btn\u保存\u单击(对象发送者,事件参数e)
{
字符串文件名=@“d:\test.bmp”;
位图bmp=新位图(pnlPaint.ClientSize.Width,pnlPaint.ClientSize.Width);
pnlPaint.DrawToBitmap(bmp,pnlPaint.ClientRectangle);
保存(文件名,ImageFormat.bmp);
}
添加您的保存代码,如果您有问题,请直接说出来

更新:我添加了两个代码段,分别执行保存和(无限)撤消操作

注1:确保使用双分叉控件:图片盒或标签,或带有on的面板

注2:这不支持单击创建点。由于没有
绘图点
无论如何,如果需要,必须解决以下问题:

  • 在当前曲线中只有一个点时,在距离鼠标点1像素处添加一个额外点
  • 或者允许单个paoint并添加一个
    FilleCircle
    以在
    Paint
    事件中显示它们
在GitHub上浏览此代码


文件夹中有一个实现,它支持方形和圆形画笔、橡皮擦和保存输出图像

实现问题属于堆栈溢出。问题出现在您未发布的代码中。您绘制面板的方式是错误的。使用它的绘制事件,不要使用CreateGraphics()。即使如此,我还是在用鼠标左键绘制,移动时需要抓取设备上下文。。因此,我认为最好在鼠标按下事件中传递它。我目前未成功使用面板的油漆事件。否。在
MouseDown
开始绘图后,
MouseMove
可以收集点,但绘图必须发生在
Paint
事件中,或从
Paint
事件触发,否则
DrawToBitmap
调用将导致无效。好的。我已经收集了分数。鼠标移动后如何调用绘制事件?pnlpoint.Refresh()/Invalidate()在面板再次变为空白之前将线条保留一秒钟。没有Winforms中的Imagebox那么薄。PictureBox具有强大的缩放和三层显示等功能,但目前的问题是基本绘图,这与Winforms非常相似,不是简单的保存问题。问题是关于“保存”图纸和空白面板是一个旁注,如OP所述。嗯,表面上,是的。但问题的原因是错误的绘画方式。保存的代码是/是正确的。对于一个实现,正面看
GifRecorder/Controls/FreeDrawPanel.cs
大约有2.45万亿现成的解决方案。通过研究最小解学习是更好的方法,依我看。
最小解
>>它是该代码的主键。;)我觉得这是解决这个问题的最好办法,尽管它仅限于划线。绘制图像、圆圈等会导致更严重的问题。但仅从我的问题来看,这是合适的。我想寻找更容易的控制,虽然这可以更容易地为所有绘画问题。我想我正在尝试做的是类似于微软的绘画,在上面投射图像,画线条,像素,形状,然后以999美元的价格出售。对于上面提到的问题,我喜欢这个。谢谢。这正是它的本来面目,但你可以把它作为基础。学习并扩展它!要继续进行更强大的绘图操作,您需要创建一个类
DrawingAction
,并用
List
替换
List
。。
DrawingAction
的属性包括:类型、颜色、笔和画笔、文本等。只需一步一个脚印。。!(有人这样做过吗