使用picturebox作为canvas并绘制文本

我想使用PictureBox作为canvas并在其上绘制一些文本并保存。

我写了这段代码,但我不确定我是否正确地这样做:

Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height); Graphics g = Graphics.FromImage(b); g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height)); // i used this code to make the background color white g.DrawString("some text", new Font("Times New Roman", 20), new SolidBrush(Color.Red), new PointF(10, 10)); pictureBox1.Image = b; 

这段代码效果很好,但是当我想要更改图像的背景颜色时,我必须重新绘制文本。

有没有办法改变背景颜色而不必重绘文本?

编写Paint程序非常有趣,但您需要提前计划所需的全部或大部分function。

到目前为止你有这些:

  • 你可以改变的背景
  • 一种通过在其上绘制文本来修改图像的方法
  • 需要将它全部保存到文件中

以下是您需要的一些内容:

  • 除了文本之外的其他工具,如线条,矩形等。
  • 可选择颜色和宽度的钢笔
  • 撤消一个或多个步骤的方法

这里有一些很好的东西:

  • 一种帮助用鼠标绘图和定位的方法
  • 其他类型的背景,如帆布或pergament纸
  • 能够以某种程度的透明度绘制
  • 重做function(*)
  • 旋转和缩放(***)
  • 级别(*****)

有些东西比其他东西更难( * )或更难( *** )但是当你决定太晚修补它们时会变得很难。

请阅读关于PictureBoxes 这篇文章 (从’实际’开始),它解释了它如何成为Paint程序的理想选择。

您的原始代码和问题存在以下问题:

  • 你似乎认为重复任何事情,比如重新绘制文本是错误的。 它不是。 Windows一直在重绘大量的东西..
  • 你混合了两个真正应该分开的任务。
  • 你还没有参数化,最值得注意的是文本的绘制应该使用几个变量:

    • 字形
    • 位置
    • 文本本身

一旦绘制线条或矩形,情况也是如此。

所以这里有一些提示如何做到正确:

  • 使用PictureboxBackgroundColor和/或BackgroundImage动态更改背景!

  • 收集要在List绘制的所有内容

  • 将所有图纸绘制 Picturebox的Image

  • 使用Paint事件在移动鼠标时绘制临时矩形或线条等支持的东西。 在MouseUp您将其添加到列表中..

所以,到了最后,让我们修复你的代码..:

你用这样的函数设置背景:

 void setBackground(Color col, string paperFile) { if (paperFile == "") pictureBox1.BackColor = col; else pictureBox1.BackgroundImage = Image.FromFile(paperFile); } 

你可以像这样调用它: setBackground(Color.White, "");

要将一段文本绘制 PictureBoxImage中,首先要确保有一个:

 void newCanvas() { Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); pictureBox1.Image = bmp; } 

现在你可以编写一个函数来写文本。 你真的不应该硬编码任何设置,更不用说文本了! 这只是一个快速而又非常脏的例子..:

 void drawText() { using (Font font = new Font("Arial", 24f)) using (Graphics G = Graphics.FromImage(pictureBox1.Image)) { // no anti-aliasing, please G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel; G.DrawString("Hello World", font, Brushes.Orange, 123f, 234f); } pictureBox1.Invalidate(); } 

请参阅此处和此处,了解有关如何创建drawAction类以存储绘图所构成的所有内容的一些注释。

最后一点是如何保存PictureBox所有层:

 void saveImage(string filename) { using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height)) { pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle); bmp.Save("yourFileName.png", ImageFormat.Png); } }