Размер UIImage, возвращаемый из «requestImageForAsset», даже близко не соответствует параметру «targetSize».

Я внимательно прочитал последнюю версию фоторамки iOS8 и пытаюсь извлечь некоторые активы из пользовательской библиотеки для отображения. Я позволяю пользователю редактировать 4 изображения одновременно. Но из-за этого мне нужно сжать изображения, иначе приложение вылетит.

Я использую PHImageManager для загрузки изображений с помощью следующего кода:

func processImages()
    {
        println("Processing")
        _selectediImages = Array()
        _cacheImageComplete = 0
        for asset in _selectedAssets
        {
            var options:PHImageRequestOptions = PHImageRequestOptions()
            options.version = PHImageRequestOptionsVersion.Unadjusted
            options.synchronous = true
            var minRatio:CGFloat = 1
            if(CGFloat(asset.pixelWidth) > UIScreen.mainScreen().bounds.width || CGFloat(asset.pixelHeight) > UIScreen.mainScreen().bounds.height)
            {
               minRatio = min(UIScreen.mainScreen().bounds.width/(CGFloat(asset.pixelWidth)), (UIScreen.mainScreen().bounds.height/CGFloat(asset.pixelHeight)))
            }
            var size:CGSize = CGSizeMake((CGFloat(asset.pixelWidth)*minRatio),(CGFloat(asset.pixelHeight)*minRatio))
            println("Target size is \(size)")
            PHImageManager.defaultManager().requestImageForAsset(asset, targetSize:size, contentMode: .AspectFill, options: options)
                {
                    uiimageResult, info in
                    var image = iImage(uiimage: uiimageResult)
                    println("Result Size Is \(uiimageResult.size)")
            }

        }

    }

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

Целевой размер (768,0 798,453531598513) Размер результата (1614,0 1678,0)

Несмотря на то, что я устанавливаю целевой размер 768x798 (в этом конкретном случае), результирующий UIImage, который он мне дает, более чем вдвое больше. Теперь по документации параметр targetSize

«Целевой размер возвращаемого изображения».

Не самое ясное объяснение, но из моих экспериментов оно НЕ соответствует этому.

Если у вас есть предложения, буду рад их услышать!


person Aggressor    schedule 30.10.2014    source источник


Ответы (4)


В Swift вы хотите сделать что-то вроде этого:

var asset: PHAsset!
var imageSize = CGSize(width: 100, height: 100)

var options = PHImageRequestOptions()
options.resizeMode = PHImageRequestOptionsResizeMode.Exact
options.deliveryMode = PHImageRequestOptionsDeliveryMode.Opportunistic

PHImageManager.defaultManager().requestImage(asset, targetSize: imageSize, contentMode: PHImageContentMode.AspectFill, options: options) {
    (image, info) -> Void in
    // what you want to do with the image here
    print("Result Size Is \(image.size)")

}

В Objective-C это выглядит примерно так:

void (^resultHandler)(UIImage *, NSDictionary *) = ^(UIImage *result, NSDictionary *info) {
    // what you want to do with the image

};

CGSize cellSize = CGSizeMake(100, 100);

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeExact;
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;

[[PHImageManager defaultManager] requestImageForAsset:self.imageAsset targetSize:cellSize contentMode:PHImageContentModeAspectFill options:options resultHandler:resultHandler];

Важное примечание. В режиме доставки Уступчивый блок результатов может вызываться несколько раз с разными размерами, но последний вызов будет иметь нужный вам размер. Лучше использовать Opportunistic, чтобы пользовательский интерфейс сначала загружал низкокачественный заполнитель, а затем обновлял его, поскольку ОС может создать более качественное изображение (вместо пустого квадрата).

person mikeho    schedule 01.09.2015
comment
Ваш код Swift повсюду. Неправильный ввод заглавных букв приведет к ошибкам. Откуда вы взяли uiimageResult? Имя параметра возвращаемого изображения — image. И что это за конструктор iImage(uiimage:), который вы вызываете? - person ; 07.07.2019
comment
@The_Androctonus Прошло почти четыре года. Кажется, я получил пример на Swift из документов PHImageManager, которые, вероятно, содержали опечатки. Я обновлю пример. Это должно быть просто удаление результата изображения, о котором вы упомянули. - person mikeho; 07.07.2019

Это потому, что requestImageForAsset будет вызываться дважды.

В первый раз он вернет изображение того же размера, например (60 * 45), которое, я думаю, является миниатюрой этого изображения.

Во второй раз вы получите полноразмерное изображение.

я использую

if ([[info valueForKey:@"PHImageResultIsDegradedKey"]integerValue]==0){ // Do something with the FULL SIZED image } else { // Do something with the regraded image }

различать два разных изображения.

Ссылка: iOS 8 PhotoKit. Получить изображение максимального размера из альбомов общего доступа к фотографиям iCloud

person Yuchao Zhou    schedule 09.10.2015
comment
Спасибо за это. Я делегировал результат изображения из requestImageForAsset другому классу, и из-за этого он вел себя неправильно. - person Christopher; 15.12.2015

Попробуйте установить resizeMode на PHImageRequestOptionsResizeModeExact и deliveryMode на PHImageRequestOptionsDeliveryModeHighQualityFormat;

PHImageRequestOptionsResizeModeExact, 
// same as above but also guarantees the delivered image is exactly targetSize (must be set when a normalizedCropRect is specified)
person gabbler    schedule 31.10.2014

Вы можете использовать PHImageManagerMaximumSize как targetSize для запроса PHImageManager.

Согласно документам в PHImageManagerMaximumSize: Размер для передачи при запросе исходного изображения или самого большого доступного отрендеренного изображения (resizeMode будет игнорироваться)

person Bruno Delgado    schedule 12.06.2016