【问题标题】:Parameter is not valid when creating Bitmap of size 6000X4500 Pixels创建大小为 6000X4500 像素的位图时参数无效
【发布时间】:2020-08-28 12:51:50
【问题描述】:

创建大分辨率位图的这行简单代码会产生parameter is not valid error

        Bitmap bitmap = new Bitmap(6500, 4500);

关于 SO 的一些问题是指 GDI+ 的内存瓶颈 参考C# "Parameter is not valid." creating new bitmap

我依赖 GDI+ 进行图像处理。更改所有代码是不切实际的。一些用户在处理大分辨率图像时报告问题。我该如何解决这个问题? 我的机器有 4GB 内存,我也尝试过构建 x64 版本的 exe。

【问题讨论】:

  • @Hans Passant 你能帮我解决这个问题吗?
  • 您是否尝试按照您引用的问题的答案之一中的建议指定PixelFormat? new Bitmap(6500, 4500, PixelFormat.Format16bppRgb555)我有 16GB,没有遇到您遇到的错误。
  • @jira 从文件创建位图时可以使用PixelFormat吗?
  • 要从文件创建位图,请使用Bitmap (string filename) 构造函数。数据已经给出了位深度等属性。
  • 这应该分配 (6500 x 4500 x 4) ~ 117M 的 RAM,到目前为止应该可以正常工作。您确定要向我们展示所有代码吗?我无法重现。或者你的确切上下文/环境是什么?

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


【解决方案1】:

这都是关于内存使用的。 我做了一个小测试,结果如下。我只创建了一个 500x500 的位图,但很多次都没有处理它:

private void button1_Click(object sender, EventArgs e)
{
    int maxIterations = 5000;
    bool exceptionOccured = false;
    for (int i = 0; i < maxIterations; i++)
    {
        Bitmap bitmap = null;
        try
        {
            bitmap = new Bitmap(500, 500);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception after " + i.ToString() + " iterations" + Environment.NewLine + ex.Message);
            exceptionOccured = true;
            break;
        }
        finally
        {
            //dispose the bitmap when you don't need it anymore (comment/uncomment to see the different result)
            //bitmap?.Dispose();
        }
    }
    if (!exceptionOccured)
    {
        MessageBox.Show("No exception after " + maxIterations.ToString() + " iterations");
    }
}

结果(未处理位图):

相同的代码,但在 finally 块中放置位图:

private void button1_Click(object sender, EventArgs e)
{
    int maxIterations = 5000;
    bool exceptionOccured = false;
    for (int i = 0; i < maxIterations; i++)
    {
        Bitmap bitmap = null;
        try
        {
            bitmap = new Bitmap(500, 500);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Exception after " + i.ToString() + " iterations" + Environment.NewLine + ex.Message);
            exceptionOccured = true;
            break;
        }
        finally
        {
            //dispose the bitmap when you don't need it anymore (comment/uncomment to see the different result)
            bitmap?.Dispose();
        }
    }
    if (!exceptionOccured)
    {
        MessageBox.Show("No exception after " + maxIterations.ToString() + " iterations");
    }
}

结果(位图被处理):

【讨论】:

  • 所以您是说错误信息具有误导性,而实际错误是内存分配错误?
  • 对,我的示例也演示了这一点。处理位图时,不会发生异常。当未释放位图时,会在某个时间点发生异常,具体取决于可用内存。位图本身不一定会产生内存泄漏。可能是应用程序中的另一个内存泄漏,当创建一个新的位图时它会崩溃。
  • 确实是内存问题。您不需要创建多个图像来复制它。在我的示例中只需一行代码在低内存机器中就足够了。
  • 这似乎不是内存的问题。我已经尝试处理数百张高分辨率图像,它似乎在机器上工作正常。但是当涉及到这组特定的图像时,一个参数is not valid 抛出错误。我会尽快上传示例图片
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 2011-09-14
  • 1970-01-01
  • 2023-03-08
  • 2015-11-25
  • 1970-01-01
相关资源
最近更新 更多