【发布时间】:2017-08-18 16:13:39
【问题描述】:
我正在开发一个完全用 c# 编写的类似 MS 绘画的程序。这是非常基本的,但我偶然发现了一个问题。所以我看到了另一个关于 MS 油漆模型的 SO 帖子。这是关于如何将最终结果保存为 .bmp 文件。我尝试使用提供的解决方案和答案并且它有效。
文件已保存。然而,当它保存时,它只保存了空白面板(我正在制作一个表单应用程序)。我只看到一篇处理此问题的 SO 帖子,但我无法合并以允许用户进行交互。以下是我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Paint
{
public partial class Form1 : Form
{
Graphics g;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
public Form1()
{
InitializeComponent();
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void blue_Click(object sender, EventArgs e)
{
p.Color = blue.BackColor;
default1.BackColor = blue.BackColor;
}
private void green_Click(object sender, EventArgs e)
{
p.Color = green.BackColor;
default1.BackColor = green.BackColor;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left)
k = 1;
}
private void panel2_MouseUp(object sender, MouseEventArgs e)
{
k = 0;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (k == 1)
{
ep = e.Location;
g = panel2.CreateGraphics();
g.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseLeave(object sender, EventArgs e)
{
k = 0; }
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
int width = Convert.ToInt32(panel2.Width);
int height = Convert.ToInt32(panel2.Height);
Bitmap bmp = new Bitmap(width, height);
panel2.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
}
}
}
}
所以我的问题是......我如何在我的 c# 表单应用程序中成功保存 .bmp 图像,就像我如何不让它保存为空白一样。在此先感谢:)
编辑
所以我尝试了第一个答案,并且我尝试了个人在 cmets 中提出的想法以及一些方法,而不是仅仅保存空白画布。该应用程序实际上只是保存了一个黑色图像。这是我最终得到的代码。我哪里做错了?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Paint
{
public partial class Form1 : Form
{
Graphics g;
Graphics h;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
Bitmap bmp =null;
public Form1()
{
InitializeComponent();
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void blue_Click(object sender, EventArgs e)
{
p.Color = blue.BackColor;
default1.BackColor = blue.BackColor;
}
private void green_Click(object sender, EventArgs e)
{
p.Color = green.BackColor;
default1.BackColor = green.BackColor;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left)
k = 1;
}
private void panel2_MouseUp(object sender, MouseEventArgs e)
{
k = 0;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (k == 1)
{
ep = e.Location;
int width = Convert.ToInt32(panel2.Width);
int height = Convert.ToInt32(panel2.Height);
Bitmap bmp = new Bitmap(width, height);
g = Graphics.FromImage(bmp);
g.DrawLine(p, sp, ep);
h = panel2.CreateGraphics();
h.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseLeave(object sender, EventArgs e)
{
k = 0; }
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
/*
Bitmap bmp = Bitmap.FromHbitmap(panel2.CreateGraphics().GetHdc());
panel2.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));*/
int width = panel2.Width;
int height = Convert.ToInt32(panel2.Height);
if (bmp == null)
bmp = new Bitmap(width, height);
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
【问题讨论】:
-
g = panel2.CreateGraphics(); Winforms 图形基本规则#1:永远不要使用
control.CreateGraphics!永远不要尝试缓存Graphics对象!使用Graphics g = Graphics.FromImage(bmp)或在控件的Paint事件中使用e.Graphics参数绘制到Bitmap bmp中。-您可以将代码用于临时内容,但用于真实的持久内容,这将是在 DrawToBitmap 中使用,您需要在 Paint 事件及其 e.Graphics 对象中进行绘制。为此,请收集您在 List.. 中绘制的每个元素 -
好的,我将如何在我的代码中实施您的第一个建议:
Graphics g = Graphics.FromImage(bmp)。我是新手,如果我测试你的耐心,我很抱歉。 (我的意思是我把它放在代码的什么地方,我还需要修改什么) -
在类级别创建位图 bmp 后,您可以简单地将
g = panel2.CreateGraphics();替换为g = Graphics.FromImage(bmp);。这没关系,但不允许您实现一些不错的撤消操作,这对于绘图应用程序来说非常好......所以最好选择更大的解决方案/重写。 Here 是一大堆例子.. -
当我替换它时,它说 bmp 在当前上下文中不存在。这是因为我还没有定义它,所以我要向上移动它还是用按钮单击功能做什么
-
是的,将其定义为类级别并在表单加载中创建它。或者在某个条件下使用它之前 (
if (bmp==null) bmp= new Bitmap(, w, h);)