【问题标题】:How to quickly batch save Bitmaps?如何快速批量保存位图?
【发布时间】:2012-06-13 22:42:09
【问题描述】:

所以我有一个相当大的源位图,所以我将它缩小了 %25 的比例,以加快图像处理的速度。最后,我有一组矩形(大约 2000 个),它们对应于缩放图像的各个部分。我正在尝试重新缩放矩形以匹配源上的相同区域,然后将该区域保存为裁剪图像。

这是我保存缩放图像的裁剪图像的初始代码:

for (int i = 0; i < cells.Count; i++)
{
    for (int j = 0; j < cells[i].Count; j++)
    {
        Cell cell = cells[i][j];

        if (cell.width < 0 || cell.height < 0)
        {
            return;
        }

        Bitmap bitmap = new Bitmap(cell.width, cell.height);

        using (Graphics c = Graphics.FromImage(bitmap))
        {
            c.DrawImage(inputBitmap, new Rectangle(0, 0, cell.width, cell.height), new Rectangle(cell.x1, cell.y1, cell.width, cell.height), GraphicsUnit.Pixel);
        }

        bitmap.Save(cellDirectory + "\\cell" + i.ToString("D2") + j.ToString("D2") + ".png", ImageFormat.Png);
    }
}

这是我更改的代码以保存原始位图的裁剪图像:

for (int i = 0; i < cells.Count; i++)
{
    for (int j = 0; j < cells[i].Count; j++)
    {
        Cell cell = cells[i][j];

        if (cell.width < 0 || cell.height < 0)
        {
            return;
        }

        int x = cell.x1 * 4;
        int y = cell.y1 * 4;
        int width = cell.width * 4;
        int height = cell.height * 4;

        Bitmap bitmap = new Bitmap(width, height);

        using (Graphics c = Graphics.FromImage(bitmap))
        {
            c.DrawImage(input, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
        }

        bitmap.Save(cellDirectory + "\\cell" + i.ToString("D2") + j.ToString("D2") + ".png", ImageFormat.Png);
    }
}

带有第一个代码的程序平均在大约 20 秒内完成,但由于某种原因,第二个版本需要 6 多分钟。我的大脑数学可能对我撒谎,但这似乎是不成比例的时间增加。

到目前为止,我所做的调试向我揭示了这一行:

c.DrawImage(input, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);

随着时间的推移需要更长的时间才能完成。我怀疑某种内存泄漏可能会导致这种情况,但我已经尝试在我能做的每个对象上手动调用 Dispose,但没有任何帮助。是否有某种我应该知道的幕后事情导致了这种情况?

【问题讨论】:

  • 您是否尝试过监控内存使用情况?任务管理器就足够了...
  • 您的代码 sn-p 未在位图上显示 Dispose()。你试过了吗?
  • 我在执行此操作之前列出了我的初始代码,但是是的,我尝试在位图和 c 上调用 Dispose()(即使 using 块应该自己处理 c)。
  • @DanielMošmondor 我运行程序的同时密切关注任务管理器的 CPU 使用率和每个内存工作集列,CPU 使用率并没有上升,而是保持不变,而工作集实际上随着时间的推移而减少(略有下降,但仍然如此)。

标签: c# .net bitmap system.drawing


【解决方案1】:

您的原始方法以原始分辨率保存文件,而新方法将宽度和高度都增加了 4 倍,即图像大小增加了 16 倍。时间差(6 分钟对 20 秒)大致成比例:

(6 * 60) / 20 = 18 times slower
4 * 4         = 16 times the image size

【讨论】:

  • 这解释了处理时间的增加,而不是绘制每个位图所需的时间增加。
  • 抱歉,我没有注意到问题的那一部分。会不会是所有这些矩形的实例化?也许你需要using (Rectangle src=...,Rectangle dest=...)。这两种实现都会发生这种情况吗?
  • 我试过了,但是 Rectangle 不能以这种方式在 using 块中使用,因为它没有实现 IDisposable。
  • 如果单元格的大小可变,是否有可能较大的单元格在数组的后面,这就是减速的原因?如果它们的大小相同,您可以通过在整个过程中保留 Bitmap Graphics 对象来加快处理速度...
  • 我找到了 AForge 库,它有一个 Crop 类,它在较大图像上花费的时间比在较小图像上花费的时间少,所以我将使用那个。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
相关资源
最近更新 更多