Как уменьшить изображение в iOS Share Extension перед загрузкой
Я создаю расширение для общего ресурса, и мне нужно масштабировать большие фотографии до меньшего размера, прежде чем загружать в свое расширение для общего ресурса.
Я использую этот код из Как изменить размер UIImage, сохраняя его соотношение сторон:
- (UIImage*) scaleImage:(UIImage*)image toSize:(CGSize)newSize {
CGSize scaledSize = newSize;
float scaleFactor = 1.0;
if( image.size.width > image.size.height ) {
scaleFactor = image.size.width / image.size.height;
scaledSize.width = newSize.width;
scaledSize.height = newSize.height / scaleFactor;
}
else {
scaleFactor = image.size.height / image.size.width;
scaledSize.height = newSize.height;
scaledSize.width = newSize.width / scaleFactor;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[image drawInRect:scaledImageRect];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
Однако, когда я пытаюсь уменьшить большое изображение из моей библиотеки фотографий (в данном случае 5415x3610, снятой с помощью зеркальной фотокамеры), происходит сбой из-за нехватки памяти. Хотя это похоже на угловой случай, мое приложение сильно зависит от iOS Share Extension для обмена фотографиями из источников, отличных от iPhone, например, с высоким разрешением с камеры.
Очевидно, что выгрузка фотографии размером 20 Мп /8 МБ без уменьшения масштаба не возможна. Как я могу уменьшить его с меньшим использованием памяти?
2 ответа
Была такая же проблема, как у вас. Операция уменьшения масштаба увеличивала использование моей памяти на +800 МБ, и иногда приложение зависало из-за использования памяти. То, что работало для меня, заменяло UIGraphicsBeginImageContextWithOptions
с новым IOS 10 UIGraphicsImageRendererFormat
, Вот мой быстрый код выполнения масштабирования изображения:
extension UIImage {
func scaled(to size: CGSize) -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = scale
let renderer = UIGraphicsImageRenderer(size: size, format: format)
return renderer.image { (_) in
draw(in: CGRect(origin: .zero, size: size))
}
}
}
Кажется, что ваше изображение и scaledImage находятся в памяти одновременно, что оба изображения могут использовать много. Вы можете попытаться выпустить свое изображение перед созданием вашего scaledImage:
//code
[image drawInRect:scaledImageRect];
image = nil;
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//code