【问题标题】:Bitmap from Drawing not render outside of Load_Form绘图中的位图未在 Load_Form 之外呈现
【发布时间】:2015-07-04 15:59:01
【问题描述】:

我正在尝试将从绘图创建的位图渲染到屏幕,但仅在再次最小化和最大化后渲染。

我按照以下步骤操作:Using Bitmaps for Persistent Graphics in C#

但只能在 Load_Form 之外的屏幕中渲染位图。

如果我输入代码:

using System.Drawing;
...

Graphics graphicsObj;
myBitmap = new Bitmap(this.ClientRectangle.Width, 
        this.ClientRectangle.Height, 
        Imaging.PixelFormat.Format24bppRgb);
graphicsObj = Graphics.FromImage(myBitmap);

Pen myPen = new Pen(Color.Plum, 3);
Rectangle rectangleObj = new Rectangle(10, 10, 200, 200);
graphicsObj.DrawEllipse(myPen, rectangleObj);
graphicsObj.Dispose();

在其他地方,例如按钮,我需要最小化和最大化才能看到图像。

编辑:

bmp是一个Bitmap全局变量我在表单事件Load_Form1

中创建了一个实例
bmp = new Bitmap(this.ClientRectangle.Width,
                 this.ClientRectangle.Height,
                 System.Drawing.Imaging.PixelFormat.Format24bppRgb);

重绘Form的Paint事件:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics graphicsObj = e.Graphics;
    graphicsObj.DrawImage(myBitmap, 0, 0, myBitmap.Width, myBitmap.Height);
    graphicsObj.Dispose();
}

但我需要在创建图纸后立即进行绘制。

【问题讨论】:

  • 您展示的代码正在创建一个位图(并泄漏一支笔)。 在哪里你认为它应该显示?您是否将其分配给某物,例如某物的图像或背景图像? mini/max 'trick' 听起来好像你缺少一个 Invalidate 来显示在 Paint 事件中绘制的东西,这与上面的代码无关..
  • 我想在打开的表单中显示。我只能在 Paint_Form1 像“编辑”中的显示那样被触发时进行绘制,但我需要在生成位图后进行绘制。我尝试使用 graphicsObj.DrawImage(myBitmap, 0, 0, myBitmap.Width, myBitmap.Height); 显示,但仅适用于 Form1_Load。我无法从创建位图的按钮单击中显示。
  • 好的,如果这就是你想要的(听起来很奇怪),你需要做的就是在创建位图后添加一个this.Invalidate();。并且不要处置您没有创建的任何东西,例如e.Grahphics!! - 当然,只需查看您向我们展示的代码,您根本不需要任何代码,当然,除了:using( Pen myPen = new Pen(Color.Plum, 3) e.Graphics.DrawEllipse(myPen, rectangleObj);' 和 Rectangle。其余的似乎没用,除非您实际上还需要位图用于其他目的.. - 最后:不建议使用 24bpp,除非您真的需要它,请使用 32bpp

标签: c# .net bitmap drawing system.drawing


【解决方案1】:

不告诉我们大局,很难推荐最佳行动方案,但让我简单地假设两个可能的目标:

  • 要么你只是想在表单上绘制一些东西

  • 或者您想显示一个位图,您可以在其中连续绘制越来越多的东西。

首先,您需要像这样编写Paint 事件:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Rectangle rectangleObj = new Rectangle(10, 10, 200, 200);
    using (Pen myPen = new Pen(Color.Plum, 3))
      e.Graphics.DrawEllipse(myPen, rectangleObj);
}

如果控制绘图的数据是动态的,则应将它们存储在类级别变量或它们的列表中,并根据需要进行更改,以便在Paint 事件中使用它们。

对于后一个目标,您添加到位图时会有不同的时间。

所以你首先创建一个可能的类级别Bitmap

    public Form1()
    {
        InitializeComponent();
        bmp = new Bitmap(this.ClientRectangle.Width,
                         this.ClientRectangle.Height);         
    }

    Bitmap bmp = null;

并且有一个或多个你可以像这样画进去的地方:

void drawALittle()
{
    Rectangle rectangleObj = new Rectangle(10, 10, 200, 200);
    using (Pen myPen = new Pen(Color.Plum, 3))
    using (Graphics G = Graphics.FromImage(bmp))
    {
        G.DrawEllipse(myPen, rectangleObj);
        //..
    }
    this.Invalidate();
}

注意我在更改Bitmap后如何InvalidateForm,所以Paint事件被触发。

还要注意,如果这些更新真的经常发生,那么在两次调用之间保持 Graphics 对象处于活动状态是一个好主意;要么将其设为像 Bitmap 这样的类变量,要么将其保存在执行所有更新的方法中,并将其作为参数传递给绘图方法。

在表单的Paint 事件中,您只需要

private void Form1_Paint(object sender, PaintEventArgs e)
{
      e.Graphics.DrawImage(bmp, 0, 0);
}       

另请注意,32bppARGB 是推荐的默认格式。 Is 用于在任何情况下显示的任何内容,因此最有效的方法是使用它开头..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 2021-06-02
    • 2020-12-13
    相关资源
    最近更新 更多