C#:使用Bitmaps时如何减少内存和CPU消耗?

时间:2011-08-22 21:32:34

标签: c# memory graphics bitmap

我有一个Windows应用程序项目,处理图像编辑(裁剪和调整大小)。不幸的是,这些图像处理消耗了大量的内存和CPU资源(很容易达到600MB或50%cpu),而且只需要裁剪和调整一个重量为2.5MB(2300 * 5400px)的gif图像。更重要的是,由于资源消耗大,程序在调整大小时会卡住......

    public static Image Resize(Image imgToResize, Size size)
    {
        Bitmap b = new Bitmap(size.Width, size.Height);
        Graphics g = Graphics.FromImage((Image)b);
        g.InterpolationMode = InterpolationMode.Default;
        g.SmoothingMode = SmoothingMode.HighSpeed;
        g.PixelOffsetMode = PixelOffsetMode.Default;
        g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
        g.Dispose();

       return (Image)b;
    }

    public static Image Crop(Image img, Point p1, Point p2)
    {
        Rectangle cropArea = new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
        return (img as Bitmap).Clone(cropArea, img.PixelFormat);
    }

我应该使用哪些方法来避免这种情况? 我已经尝试将它压缩成几种格式的内存流,但它没有帮助(甚至使它变得更糟)

注意:我使用标准的.NET绘图库:System.Drawing,System.Drawing.Imaging

5 个答案:

答案 0 :(得分:3)

您的代码正在创建映像的副本,因此在调用这些方法时,您应该期望非托管内存使用率上升。重要的是你用原版做的事情。你应该明智地摆脱它,这样它就不再占用记忆。您必须调用其Dispose()方法来执行此操作。等待垃圾收集器执行它需要太长时间。 Bitmap类只需很少的托管内存,但需要大量非托管内存。

答案 1 :(得分:1)

从此问题的早期版本开始:http://snippets.dzone.com/posts/show/4336

此外,AForge.net有几个调整大小函数

答案 2 :(得分:0)

这是一个棘手的问题,而且我之前遇到过一个问题。您可以根据文件的大小将图像拆分为x个,然后将每个图像保存到磁盘以确保内存清洁。

接下来,每次调整一个组件映像的大小,确保在继续下一个组件之前处理组件。完成所有操作后,将它们拼接在一起,然后裁剪。

使用这种方法的主要问题 - 如果你正在调整向上,这种方法会在你的图像中加入接缝,因为插值不会有周围的像素猜测。但我认为这种方法适用于向下调整大小。

HTH。

答案 3 :(得分:0)

又一次暗示:

例如在调整大小时,就像@Hans指出的那样,你创建了一个新的Bitmap,哪一个是你的瓶颈。

但是,如果您只是绘制图像已调整大小,最初加载的图像(显然您之前在磁盘上创建了原始图像的备份文件)。

裁剪后,如果您只是绘制用户裁剪的位图的一部分,那么用户将只看到该矩形。 ?

我的意思是一般来说,对你已有的图像进行操作,并尝试(尽可能多)不为它初始化新对象。

问候。

答案 4 :(得分:-2)

编写Application.DoEvents();在你的功能中,至少它不会卡住