【问题标题】:C# bitmap - Parameter is not validC# 位图 - 参数无效
【发布时间】:2016-08-11 15:18:44
【问题描述】:

我正在用 c# 制作一个基本的窗口游戏,但我无法为屏幕创建基本位图。我在屏幕上有一个面板,我希望能够绘制到它,所以我使用以下代码:

 public partial class GameWIndow : Form
{
    public GameWIndow()
    {
        InitializeComponent();
    }





    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        Bitmap buffer;
        buffer = new Bitmap(Width, Height);
        Task.Factory.StartNew(() =>
        {
            using (Graphics g = Graphics.FromImage(buffer))
            {
                g.FillRectangle(new SolidBrush(Color.PaleGoldenrod), 10, 10, 100, 100);
            }
            this.Invoke(new Action(() =>
            {
                this.BackgroundImage = buffer;
            }));
        });
    }

当这个运行它给我错误“参数无效”的行

buffer = new Bitmap(Width, Height);

Width和Height分别是900和700,都是整数。

如果问题是我做的完全错误,有什么更好的方法来完成这个。

--------编辑-------

我查看了你们的 cmets,看来我上面所做的非常糟糕,所以我尝试了不同的方法,但我不确定这是否更好。

    private Game game;
    private Thread renderThread;
    private Stopwatch stopwatch = new Stopwatch();

    public GameWindow()
    {
        InitializeComponent();

        //Starts game
        game = new Game();

        //Starts rendering
        this.DoubleBuffered = true;
        renderThread = new Thread(new ThreadStart(draw));
        renderThread.Start();
    }

    //Runs when screen is asked to refresh
    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        //Sends graphics to game class where it draws game
        game.draw(e.Graphics);

    }

    private void draw()
    {
        stopwatch.Start();

        while (true)
        {

            //If 1/60th of a sec has passed
            if (stopwatch.ElapsedMilliseconds > 1000D / 60D)
            {

                stopwatch.Restart();
                Invalidate();

            }
        }

    }

上面的代码运行不正确,我不太清楚为什么,如果有人能提供帮助,我将不胜感激。然而,我的主要问题不是如何解决它,而是这是否是一种有效或“正确”的绘画方式。

【问题讨论】:

  • 问题很可能是你这样做完全错误。我不知道具体为什么会出现该错误,但是禁止从创建它的线程以外的任何其他线程修改 GUI。 (仔细阅读,这绝对不是您收到此错误的原因,但该规则仍然适用。)
  • 你想做什么?这看起来有点可疑。 PaintEventArgs 已经包含一个 Graphics 的实例,你应该在上面绘制。
  • 如果您为该控件启用双缓冲样式,您可以用最直接的方式编写Paint事件处理代码。
  • 面板不应该是设置表单背景图像的面板。如果您只想绘制面板,请绘制面板。并使用面板的尺寸:buffer = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height);
  • 你更新的代码更糟糕。不要在绘制事件中运行 while 循环。另外,你没有画任何东西。为了让它工作,我会放弃线程,只使用一个基本的计时器来使你的绘图无效。

标签: c# .net multithreading graphics bitmap


【解决方案1】:

正如@TaW 所暗示的,存在很多问题。我假设这是 WinForms 应用程序的 Paint 事件处理程序?这是您应该告诉我们的重要信息。

每当表单内容中的任何内容需要重绘时,操作系统都会调用 Paint 事件处理程序。 PaintEventArgs 为您提供必须绘制的 ClipRectangle 和必须绘制的 Graphics 上下文。你应该只在你的处理程序中绘制它;您不得执行任何其他处理、启动线程或执行任何 I/O。如果您需要加载图像或执行 I/O,您必须在处理程序之外执行此操作,将结果保存到表单属性,使要绘制的矩形无效,然后使用保存的属性在您的 Paint 处理程序中进行绘制。它应该看起来像这样:

private void Panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawImage(_buffer, _position);
}

_buffer 是什么? Image 您在处理程序之外填写。 _position?您在处理程序之外更新的位置。

不要在 Paint 处理程序中分配缓冲区、Brushes 或图像;在处理程序之外创建它们并重用它们。如果您需要使用长时间进程或网络连接的结果来更新您的控件,请在您的处理程序之外创建一个TaskBackgroundWorker,并让完成例程保存结果并使您的控件无效。在您的处理程序中使用保存的结果。如果您需要执行某种动画,请预先创建所有动画帧,使用计时器使您的显示无效,并在您的处理程序中绘制正确的帧。

WinForm 图形是一个很大的话题,你需要买一本书或学习教程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-03
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多