Пик потребления памяти при изменении размера, повороте и обрезке изображений на iPhone - PullRequest
1 голос
/ 01 июля 2011

У меня есть класс ImageManipulator, который выполняет обрезку, изменение размера и поворот изображений с камеры на iPhone.

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

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

Это то, что я сейчас делаю:

CGAffineTransform transform = CGAffineTransformIdentity;
// Check for orientation and set transform accordingly...
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);

// Create a bitmap context with the image that was passed so we can perform the rotation
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                         CGImageGetBitsPerComponent(self.CGImage), 0,
                                         CGImageGetColorSpace(self.CGImage),
                                         CGImageGetBitmapInfo(self.CGImage));

// Rotate the context
CGContextConcatCTM(ctx, transform);

// Draw the image into the context
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);

// Grab the bitmap context and save it to the disk...

Даже после попытки уменьшить изображение до половины или даже 1/4 размера, я все еще вижу шипы, и мне интересно, есть ли другой / более эффективный способ сделать вращение, как описано выше? 1011 *

Заранее спасибо за ответы. Рог

Ответы [ 4 ]

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

Что вы можете сделать:

  1. Уменьшите изображение еще больше (чего вы, вероятно, не хотите)

  2. Не забудьте отпустить все, как только закончите с ним

  3. Живи с этим

Я бы выбрал вариант 2 и 3.

Редактирование изображений очень ресурсоемко, поскольку загружает все необработанные данные несжатого изображения в память для обработки. Это неизбежно, поскольку нет абсолютно никакого другого способа изменить изображение, кроме как загрузить все необработанные данные в память. Пики потребления памяти на самом деле не имеют значения, пока приложение не получит предупреждение о памяти, в этом случае быстро избавьтесь от всего, прежде чем оно выйдет из строя. Тем не менее, очень редко вы получаете предупреждение о нехватке памяти, потому что мое приложение регулярно загружает в память один файл размером более 10 Мб, а я не получаю предупреждения даже на старых устройствах. Так что с шипами все будет в порядке.

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

Если вы сохраняете в JPEG, я полагаю, что альтернативный подход заключается в том, чтобы сохранить изображение как есть, а затем установить поворот на то, что вы хотите, манипулируя метаданными EXIF? См. Например этот пост . Простой, но, вероятно, эффективный, даже если вам нужно держать в памяти полезные байты изображения;)

0 голосов
/ 06 июля 2011

Как упомянул Anomie, CGBitmapContextCreate создает контекст.Мы должны выпустить это с помощью

CGContextRelease(ctx);

Если у вас есть какие-либо другие объекты, созданные с использованием create или copy, они также должны быть освобождены.Если это CFData, то

CFRelease(cfdata);
0 голосов
/ 03 июля 2011
  • Вы пробовали проверять утечки памяти и анализировать распределение?
  • Если изображение по-прежнему слишком велико, попробуйте повернуть изображение по частям, а не целиком.
...