如何保存PictureBox中包含FillPie等绘制图形的图像?
问题出在哪?
- 你现在保存的是
pictureBox1.Image,这其实只是PictureBox的原始背景图,而Paint事件里用e.Graphics画的绿色矩形、十字线、FillPie都是临时渲染在控件界面上的,根本没写入到pictureBox1.Image对象里,所以保存后自然看不到这些绘制内容。 - 另外,在Paint事件过程中执行保存操作也不合理——控件刷新、窗口重绘时会多次触发Paint事件,会导致重复保存,完全不符合单次保存的预期。
解决方案
推荐两种实用的实现方式:
方法一:用DrawToBitmap直接捕获控件完整画面(最简单)
直接调用PictureBox自带的DrawToBitmap方法,把控件上显示的所有内容(包括你画的所有图形)都复制到Bitmap里,再保存即可。
修改步骤:
- 删掉
DrawMyPie里的保存代码,避免在Paint事件里重复触发保存。 - 添加一个独立的保存触发逻辑,比如加个按钮,点击时执行保存:
// 修改后的DrawMyPie,去掉保存代码 public void DrawMyPie(int myPiePerecent, Color myPieColor, Graphics myPieGraphic, Point myPieLocation, Size myPieSize) { using (SolidBrush brush = new SolidBrush(myPieColor)) { myPieGraphic.FillPie(brush, new Rectangle(myPieLocation, myPieSize), Convert.ToSingle(myPiePerecent * 360 / 100), Convert.ToSingle(15 * 360 / 100)); } } // 按钮点击事件示例,执行保存逻辑 private void btnSave_Click(object sender, EventArgs e) { // 把counter改成类级别的字段,避免每次点击重置计数 static int counter = 0; // 创建和PictureBox一样大的Bitmap using (Bitmap saveBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height)) { // 将控件的全部显示内容绘制到Bitmap上 pictureBox1.DrawToBitmap(saveBitmap, new Rectangle(0, 0, saveBitmap.Width, saveBitmap.Height)); // 保存到指定路径 saveBitmap.Save(@"d:\" + counter + "mybitmap1.bmp"); counter++; } }
方法二:统一绘制逻辑到Bitmap(适合精细控制绘制内容)
把所有绘制逻辑抽成一个独立方法,既用于PictureBox的界面显示,也用于绘制到Bitmap上保存,这样可以精确控制每一部分的绘制细节。
修改示例:
// 统一的绘制方法,所有图形都在这里画 private void DrawAllGraphics(Graphics g) { g.SmoothingMode = SmoothingMode.AntiAlias; // 画绿色矩形 g.DrawRectangle(Pens.Green, 0, 0, pictureBox1.Width - 1, pictureBox1.Height - 1); // 画红色十字线 using (Pen p = new Pen(Color.Red)) { g.DrawLine(p, 256, 0, 256, 512); g.DrawLine(p, 0, 256, 512, 256); } // 画Pie DrawPieOnPicturebox(g); } // Paint事件里调用统一绘制方法 private void pictureBox1_Paint(object sender, PaintEventArgs e) { DrawAllGraphics(e.Graphics); } // 保存方法 private void btnSave_Click(object sender, EventArgs e) { static int counter = 0; using (Bitmap saveBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height)) { using (Graphics g = Graphics.FromImage(saveBitmap)) { // 把所有图形绘制到Bitmap上 DrawAllGraphics(g); } saveBitmap.Save(@"d:\" + counter + "mybitmap1.bmp"); counter++; } } // DrawPieOnPicturebox、DrawMyPie方法保持不变,记得删掉DrawMyPie里的保存代码
关键注意点
- 别在Paint事件里执行保存操作,控件刷新时会多次触发Paint,导致重复保存。
- 用
using语句包裹Bitmap、Graphics、Brush、Pen这些资源,确保用完就释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

