2013-07-30 8 views
0

Я должен разделить 50 квадратных изображений (600 пикселей x 600 пикселей) на 9 квадратов с равным размером (200x200). Чтобы получить каждую часть, я использую метод:CoreGraphics: массовое разделение изображений

-(UIImage *)getSubImageFrom:(UIImage *)img WithRect:(CGRect)rect 
{ 
UIGraphicsBeginImageContext(rect.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

// translated rectangle for drawing sub image 
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height); 

// clip to the bounds of the image context 
// not strictly necessary as it will get clipped anyway? 
CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height)); 

// draw image 
[img drawInRect:drawRect]; 

// grab image 
UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext(); 

CGContextRelease(context); 

return subImage; 
} 

И это было достаточно быстро для меня ... с сегодняшнего дня. Я использовал для загрузки изображений с использованием метода [UIImage imageNamed:]. Этот метод НЕ выполняет автоопределение памяти, пока приложение не получит предупреждение о памяти ... Это было неприемлемо для меня.

Итак, я начал использовать [UIImage imageWithContentsOfFile]. Проблемы с распределением памяти исчезли ... к сожалению, мой метод обрезки (- (UIImage *) getSubImageFrom: (UIImage *) img WithRect: (CGRect) rect) начал работать 20 раз медленнее! Его сейчас несколько часов с тех пор, как я начал искать решение ... без результата. Надеюсь, ты поможешь мне.

С уважением!

PS. Я попытался использовать советы по этому вопросу CGContextDrawImage is EXTREMELY slow after large UIImage drawn into it, без каких-либо результатов.

ответ

0

Это то, что мы называем «компромисс». Вы жалуетесь, что +[UIImage imageNamed:] делает вещи быстрее, но использует больше памяти, и что +[UIImage imageWithContentsOfFile:] работает медленно, но не использует столько памяти. Причина, по которой последний медленный, заключается в том, что каждый раз, когда вы вызываете +[UIImage imageWithContentsOfFile:], он должен читать и декодировать изображение с «диска», и это требует времени (нетривиальное количество времени, как вы узнали). Когда вы используете +[UIImage imageNamed:], он считывается и декодируется один раз, а затем результат операции чтения/декодирования сохраняется в памяти до тех пор, пока не появится предупреждение о памяти. Это означает, что последующие обращения к этому изображению (перед предупреждением о памяти) будут быстрыми.

Звучит неплохо, если вы будете кэшировать изображения в кеше, жизнь которого вы можете контролировать. NSCache будет очевидным выбором, поскольку он также зацепил в крючками системной памяти, но вы можете явно удалить вещи раньше, используя -removeObjectForKey:

Другой подход может быть для создания суб-изображений один раз и записать их на диск (смотреть NSCachesDirectory за хорошее место, чтобы положить такие вещи). Это избавит от необходимости делать это (относительно дорогое) подмножество операции более одного раза, а меньшие изображения (при условии, что они вам не нужны все сразу) может быть быстрее загружаться с диска, чем большие изображения.

Чтобы играть адвоката дьявола в течение минуты: Если UIImage делает правильную вещь, когда появляется предупреждение о памяти, почему вы заботитесь о том, чтобы она использовала память? Является ли использование этой памяти причиной того, что ваше приложение будет убито? (Я знаю по опыту, что предупреждения о памяти не блокируются - то есть у вас не обязательно достаточно времени, чтобы сократить потребление до того, как ваш процесс будет убит, - но действительно ли у вас есть эта проблема? Положите иначе, есть ли вероятность того, что ваши усилия по сокращению потребления памяти могут квалифицироваться как преждевременная оптимизация?