Установите максимальный размер для CGImageRef из ALAssetRepresentation

В настоящее время я использую следующий код для получения UIImage из ALAsset в приложении iOS.

ALAssetRepresentation *rep = [self.asset defaultRepresentation];
CGImageRef ref = [rep fullResolutionImage];
ALAssetOrientation orientation = [[self.asset valueForProperty:@"ALAssetPropertyOrientation"] intValue];
UIImage *image = [UIImage imageWithCGImage:ref scale:1.0 orientation:(UIImageOrientation)orientation];

Это работает очень хорошо, пока изображение достаточно маленькое (например, снятое камерой устройства). Однако, если изображение слишком большое (6000px^2 и больше), приложению не хватит памяти на этом шаге:

CGImageRef ref = [rep fullResolutionImage];

Я хотел бы обнаружить это условие до сбоя приложения или (в идеале) установить максимальный размер возвращаемого изображения.

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

Кроме того, использование размера ресурса в байтах ненадежно, поскольку форматы с высокой степенью сжатия, такие как JPG, могут быть небольшими по упакованному размеру, но все же потреблять слишком много памяти, если их размер в пикселях высок (изображения с низкой детализацией, сильно сжатые изображения).

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


person 0x90    schedule 12.01.2012    source источник


Ответы (1)


ОБНОВИТЬ:

После некоторого обсуждения в комментариях.

Вы можете получить информацию Exif о файлах/активах с помощью вызова

[asset metadata]

Ссылка, которую я нашел, находится здесь sarofox.alasset-image-metadata. На странице также показано, как получить отдельные свойства. Это должно позволить вам получить размеры в пикселях до того, как вы откроете файл/ресурс.

МОЙ СТАРЫЙ ОТВЕТ:

ниже, на случай, если кто-то найдет эту идею полезной.:

Это всего лишь предположение. Но не могли бы вы использовать ALAssetRepresentation getBytes:fromOffset:length:error:

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

Запустите проверку с помощью fromOffset от начала размера файла. И длина до (желаемого максимума) конца размера файла.

Прочитайте размер в буфере. Если он меньше, чем запрос, то все в порядке. Если он точно такой же, как запрошенный диапазон, то в файле может быть больше (он может быть больше).

Если это так, запустите новый запрос getBytes:fromOffset:length:error:*, ​​на этот раз с fromOffset из длины последнего запроса и новой длины.

Затем вы можете сложить результаты и определить, будет ли весь файл слишком большим.

Но никогда не используйте слишком большой буфер/файл.

person markhunte    schedule 12.01.2012
comment
Спасибо за идею. Проблема в том, что размер файла сжатого изображения не имеет значения. Например, PNG размером 6000px*6000px, который содержит только белый цвет, будет иметь очень маленький размер в байтах, но станет очень большим после распаковки для просмотра. - person 0x90; 13.01.2012
comment
Я вижу, вы хотите получить проецируемый размер пикселя - person markhunte; 13.01.2012
comment
да. Я обновил вопрос, чтобы сделать это более ясным. Спасибо, что указали на это. :) - person 0x90; 13.01.2012
comment
Покопавшись, я нашел sarofax.wordpress.com/2011/07/ 10/alasset-image-metadata, что, по-видимому, подразумевает, что вы можете получить данные exif из актива, используя [метаданные актива] . Если это будет полезно, я обновлю свой ответ. - person markhunte; 13.01.2012
comment
Да, это помогает! Пожалуйста, обновите свой ответ, чтобы я мог проголосовать и отметить его как правильный. - person 0x90; 13.01.2012