Исключение переполнения памяти при создании растровых изображений в цикле - PullRequest
1 голос
/ 08 июля 2011

Мне нужно импортировать большое количество обрезанных изображений из множества изображений, которые все готовы сохранить в моей базе данных. Я пытался использовать операторы и избавляться от своих растровых объектов каждый раз. Но я все еще получаю исключение переполнения памяти, что моей системе не хватает памяти.

Вот пример кода того, что я делаю.

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. Но у меня было другое приложение для этого кода другого проекта. Я просто не могу преодолеть переполнение памяти.

Мне нужно просмотреть около 20 тыс. Изображений.

Ответы [ 3 ]

5 голосов
/ 08 июля 2011

Вы не избавляетесь от потоков памяти. Все, что реализует IDisposable, должно быть утилизировано.

Создана ли утечка памяти, если MemoryStream в .NET не закрыта?

1 голос
/ 08 июля 2011

Ants memory profiler - неоценимый инструмент для устранения проблем такого типа. На первый взгляд, единственная проблема, которую я вижу, это то, что у вас есть утечка, если вы когда-нибудь выбросите исключение.

я бы использовал using вместо того, чтобы вручную утилизировать ваши объекты и убедиться, что вы регистрируете исключения. Если этого не происходит, и профилировщик памяти не показывает каких-либо проблем, попробуйте добавить GC.collect(), поскольку это может помочь, если куча больших объектов фрагментируется, что относительно вероятно для такого рода кода.

0 голосов
/ 05 июля 2016

Вам доступно определенное количество опций, которые могут быть полезны, например сжатие растровых изображений, повторное использование растровых изображений, масштабирование растровых изображений, перехват растровых изображений.

Перехват растровых изображений

Перехват OutOfMemoryErrorдекодирование Bitmap

Recycle bitmaps

Android: Bitmap recycle () как это работает?

сжатие растровых изображений

Как сделать растровое сжатие без изменения размера растрового изображения?

Масштабирование растрового изображения

Android - масштабирование и сжатие растрового изображения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...