C# 在绘图程序中保存位图
我正在开发一个完全用c#编写的类似MS paint的程序。这很基本,但我偶然发现了一个问题。所以我看到了另一篇关于MS绘画模型的So帖子。它是关于如何将最终结果保存为.bmp文件。我试着使用提供的解决方案和答案,效果很好 文件已保存。然而,当它保存时,它只保存了空白面板(IM制作一个表单应用程序)。我只看到过一篇关于这个问题的文章,但我无法将其合并以允许用户进行交互。以下是我的代码:C# 在绘图程序中保存位图,c#,winforms,bitmap,C#,Winforms,Bitmap,我正在开发一个完全用c#编写的类似MS paint的程序。这很基本,但我偶然发现了一个问题。所以我看到了另一篇关于MS绘画模型的So帖子。它是关于如何将最终结果保存为.bmp文件。我试着使用提供的解决方案和答案,效果很好 文件已保存。然而,当它保存时,它只保存了空白面板(IM制作一个表单应用程序)。我只看到过一篇关于这个问题的文章,但我无法将其合并以允许用户进行交互。以下是我的代码: using System; using System.Collections.Generic; using Sy
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#forms应用程序中成功保存.bmp图像,如如何不将其保存为空白。提前感谢:)
编辑
因此,我尝试了第一个答案,也尝试了个人在评论中提出的想法和一些方法,而不仅仅是保存一张空白画布。应用程序实际上只是保存一个黑色图像。这是我最后得到的代码。我哪里出错了
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);
}
}
}
}按如下方式使用并保存:
Bitmap bitMap = Bitmap.FromHbitmap(g.GetHdc());
bitMap.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
这是一个修订版,与我在评论中告诉你的差不多
public partial class Form2 : 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 Form2()
{
InitializeComponent();
bmp = new Bitmap(panel2.ClientSize.Width, panel2.ClientSize.Height);
g = Graphics.FromImage(bmp);
g.Clear(panel2.BackColor);
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void color_Click(object sender, EventArgs e)
{
Control ctl = sender as Control;
p.Color = ctl.BackColor;
default1.BackColor = ctl.BackColor;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ep = e.Location;
g.DrawLine(p, sp, ep);
h = panel2.CreateGraphics();
h.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
请注意:
- 我将调色板控件的所有单击映射为一个
- 通过在移动中进行按钮测试,我消除了标志
k
- 我保留了缓存的图形
;这通常是不推荐的,但当我们继续绘制成一个位图时,相同的位图是可以的g
- 我已删除位图的所有重复声明
bmp
- 我不知道picturebox是做什么的,所以我没碰密码
- 既然你没有跟踪所有的动作,你就不能很好地撤销李>
- 由于所有线都是单独绘制的,因此使用更宽和/或半透明的笔无法获得良好的效果,因为重叠端点看起来很糟糕
关于简单涂鸦的更好解决方案,请参见,在您研究了它之后,您可以处理更好的解决方案,它将允许您使用各种绘图工具。我已经重写了我的函数:`if(dialog.ShowDialog()==DialogResult.OK){int width=Convert.ToInt32(panel2.width);int height=Convert.ToInt32(panel2.height);Bitmap-Bitmap=Bitmap.FromHbitmap(g.GetHdc());Bitmap.Save(dialog.FileName,System.Drawing.Imaging.ImageFormat.Bmp);}`并且System.Drawing.dll错误中出现“System.InvalidOperationException”。它表示该对象(即g)正在其他地方使用,请尝试以下操作:
Bitmap Bitmap=Bitmap.FromHbitmap(panel2.CreateGraphics())代码>它给了我一个错误,无法将System.drawing.graphics转换为System.IntPtrOh。很抱歉,这是打字错误。尝试使用Bitmap Bitmap=Bitmap.FromHbitmap(panel2.CreateGraphics().GetHdc())
g=panel2.CreateGraphics();Winforms graphics基本规则#1:切勿使用控件。CreateGraphics
!切勿尝试缓存图形
对象!使用Graphics g=Graphics.FromImage(bmp)
或在控件的Paint
事件中,使用e.Graphics
参数将bmp绘制到位图中您可以将该代码用于临时内容,但用于真实、持久的内容,这些内容将用于在Paint事件中绘制的DrawToBitmap及其e.Graphics obejct中。要这样做,请收集您在列表中绘制的每个元素。好的,那么,我将如何实现您的第一个建议:Graphics g=Graphics.FromImage(bmp)
到我的代码中。我是新手,所以如果我在考验你的耐心,我很抱歉。(我的意思是,我把它放在代码中的什么地方,我还需要修改什么)您可以简单地替换g=panel2.CreateGraphics()
byg=Graphics.FromImage(bmp)代码>在类级别创建位图bmp后。这是可以的,但不允许你实现撤销,这对于一个绘画应用程序来说太好了。。。因此,最好采用更大的解决方案/重写。是一大堆的例子。当我替换它时,它说bmp在当前上下文中不存在。这是因为我还没有定义它,所以我要向上移动它,或者我该如何使用按钮单击功能是的,将其定义为类级别并在表单加载中创建它。或者在条件下使用它之前(如果(bmp==null)bmp=new Bitmap(,w,h);
)一个快速问题(ps感谢您的回答):现在保存到黑色背景。如何将其保存到白色背景?g.Clear(panel2.BackColor)代码>实际上它保存到面板的背景色。请注意,默认情况下,面板是透明的,而且许多查看器(例如Irfanview)无法显示透明度。(IrfanView将其显示为黑色!)因此,您看到的可能实际上是透明的??您可以将面板更改为白色,也可以将面板更改为清晰的颜色。白色。。