1

我必须从已准备好存储在我的数据库中的许多图像中导入大量图像裁剪。我每次都尝试过使用语句并处理我的位图对象。但是我仍然收到内存溢出异常,表明我的系统内存不足。

这是我正在做的一些示例代码。

public void CropImage(List<ImageClass> data)
{
    foreach (var obj in data)
    {
        //I have a data base method that returns a data object that 
        //contains the file bytes of the image id in data: 'file'
        //My List<ImageClass> data contains an ID of the original image
        //start x,y coords for the upper left corner of the rectangle,
        //and the width and height of the rectangle.

        Image img = Image.FromStream(new MemoryStream(file.Data));
        Bitmap bmp = new Bitmap((Bitmap)img);
        Rectangle cropArea = new Rectangle(obj.x_coordinate,
                                           obj.y_coordinate,
                                           obj.width,
                                           obj.height);

        Bitmap cropImage = bmp.Clone(cropArea, bmp.PixelFormat);

        SaveFile(cropImage, file, obj.scanID);

        img.Dispose();
        bmp.Dispose();
        cropImage.Dispose();
    }
}


    public void SaveFile(Bitmap cropImage, FileData file, int OCRscanID)
    {
        EncoderParameters encoderParams = new EncoderParameters();
        encoderParams.Param[0] = new EncoderParameter(
                                          System.Drawing.Imaging.Encoder.Quality,
                                          50L);

        ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
        MemoryStream newImage = new MemoryStream();
        cropImage.Save(newImage, codecInfo, encoderParams);

        byte[] newData = newImage.ToArray();

        //Saving data bytes to database of the cropped image 
    }

    private ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        int j;
        ImageCodecInfo[] encoders;
        encoders = ImageCodecInfo.GetImageEncoders();
        for (j = 0; j < encoders.Length; ++j)
        {
            if (encoders[j].MimeType == mimeType)
                return encoders[j];
        }
        return null;
    }

我知道我可以修剪一些代码,例如搜索编码器以仅使用图像/jpeg。但是我有另一个应用程序用于这个代码另一个项目。我似乎无法克服内存溢出。

我需要循环浏览大约 20k 图像。

4

3 回答 3

5

你没有处理你的内存流。所有实现的东西都IDisposable应该被处理掉。

如果 .NET 中的 MemoryStream 未关闭,是否会产生内存泄漏?

于 2011-07-08T01:07:45.113 回答
1

Ants 内存分析器是调试此类问题的宝贵工具。乍一看,我看到的唯一问题是,如果你抛出异常,就会发生泄漏。

我要做的是使用using而不是手动处理您的对象并确保您正在记录异常。如果这不起作用并且内存分析器没有向您显示任何问题,请尝试添加 aGC.collect()因为如果您的大对象堆变得碎片化,这可能会有所帮助,这种代码相对可能。

于 2011-07-08T01:06:36.453 回答
0

有一定数量的选项可供您使用,它们可能会有所帮助,例如位图压缩、位图回收、位图缩放、捕获位图。

捕捉位图

在解码位图时捕获 OutOfMemoryError

回收位图

Android:位图回收()它是如何工作的?

位图压缩

如何在不改变位图大小的情况下使位图压缩?

位图缩放

Android - 缩放和压缩位图

于 2016-07-05T15:01:34.870 回答