Подтвердить что ты не робот

Определите самый большой размер изображения PHASset, доступный на устройстве iOS

Как я могу определить самый большой размер изображения PHAsset, который доступен на устройстве iOS, где "доступным" я имею в виду в настоящее время на устройстве, не требуя загрузки сети из iCloud Photo Library?

Я разрабатываю приложение, в котором коллекция эскизов отображается в UICollectionView (так же, как приложение "Фото" ), а затем пользователь может выбрать изображение, чтобы увидеть его в полном размере. Изображение полного размера загружается из iCloud, если необходимо. Тем не менее, я хочу показать пользователю самую большую возможную версию изображения до тех пор, пока не будет доступен полный размер.

Способ работы с фотографиями довольно странный:

В представлении коллекции я использую PHCachingImageManager в кеш (и позже request) с targetSize размером 186x186 пикселей (в два раза меньше размеров UICollectionViewCell из-за масштабирования сетчатки).

Это работает очень хорошо, с очень быстрой прокруткой и без задержки при заполнении ячеек изображениями. Проверяя размер возвращенных изображений, все они примерно 342x256 пикселей. То, что на моем iPhone 6 с iCloud Photo Library включено и "Оптимизировать хранилище" включено, поэтому для большинства изображений хранятся только маленькие эскизы на устройстве.

Однако нечетная часть состоит в том, что если я затем запрошу полную (или намного большую) версию любого изображения, либо с помощью PHCachingImageManager, либо PHImageManager.defaultManager(), используя PHImageRequestOptionsDeliveryMode.Opportunistic, первое (низкое качество) изображение, которое возвращается, представляет собой крошечную почтовую марку размером 60х45 пикселей, которая выглядит ужасной на весь экран, пока в конечном итоге не загрузится изображение полного размера, чтобы заменить его.

Понятно, что на устройстве уже есть большие эскизы (342x256), так как они были показаны только в виде коллекции! Так почему, черт возьми, он не возвращает их в качестве первого изображения "низкого качества", пока не будет загружен полный размер? Чтобы убедиться, что изображения 342x256 действительно были на устройстве, я запустил код в режиме полета, чтобы не было доступа к сети.

Я обнаружил, что если бы я запросил размер до 256x256, я бы получил возвращенные 342x256 изображения. Как только я стал больше (даже 1 пиксель), он сначала вернет мне 60x45 изображений, а затем попытается загрузить полноразмерное изображение.

Я изменил свой код, чтобы сначала выполнить запрос 256x256, а затем запрос полного размера с PHImageRequestOptionsDeliveryMode.HighQualityFormat (который не возвращает маленькое промежуточное изображение), и это прекрасно работает. Это также то, что должно делать приложение iOS Photos, поскольку оно отображает относительно высокое качество эскизов при загрузке полного изображения.

Итак, с этим фоном, как узнать, какой самый большой размер изображения устройства для PHAsset? Является 256x256 магическим числом или зависит от того, как iCloud Photo Library оптимизирует пространство (на основе размера библиотеки и доступного хранилища устройств)?

Конечно, кажется, что ошибка в том, что Photos Framework не возвращает наибольшее изображение, доступное в данный момент (когда его спрашивают о размере, который больше, чем в данный момент), и чтобы получить самый большой размер, который он имеет, вы должны спросить об этом размере или меньше, потому что, если вы попросите большего, вы получите миниатюру размером 60x45! Bizarre.

ОБНОВЛЕНИЕ: Отчет об ошибке, представленный Apple: https://openradar.appspot.com/25181601
Пример проекта, демонстрирующий ошибку: https://github.com/mluisbrown/PhotoKitBug

4b9b3361

Ответ 1

Используя пример проекта, опубликованный в вопросе, я смог воспроизвести проблему в симуляторе, но когда я сделал следующее изменение, я получил бы только самое большое изображение:

let targetSize = PHImageManagerMaximumSize

Ответ 2

На самом деле я не знаю причины, по которой Apple вернет ухудшенное изображение 45 * 60 с PHImageResultIsDegradedKey = 1. Для меня я просто сначала запрашиваю изображение 256 * 256 с методом доставкиMode PHImageRequestOptionsDeliveryModeHighQualityFormat, затем я использую другие PHImageRequestOptions для запроса изображения полного размера, как показано ниже:

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = YES;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){
// code to update the iCloud download progress
});

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
// code to update UIImageView or something else.
});

И я думаю, что Instagram может использовать это аналогичное решение для обработки изображения из iCloud.

Ответ 3

[imageManager requestImageForAsset:asset
              targetSize: PHImageManagerMaximumSize
              contentMode:PHImageContentModeAspectFill
              options:nil
resultHandler:^(UIImage *result, NSDictionary *info)
{
    result;
}];