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

IOS UIImageView масштабирование изображения вниз производит изображение с псевдонимом на iPad 2

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

Изображения обычно уменьшаются примерно с 500 пикселей по 500 пикселей до 100 пикселей x 100 пикселей. На сетчатке iPad они очень хорошо отображаются, пока на iPad2 они плохо сглажены, пока размер не приблизится к размеру собственного изображения.

Примеры:

Original Image

Оригинальное изображение

Retina iPad 100x100

Retina iPad рендеринг при 100px x 100px

iPad 2 100x100

iPad 2 рендеринг при 100px x 100px

Разница между iPad 2 и новым iPad может быть просто разрешением экрана, или может быть, что графический процессор лучше оснащен масштабированием изображений. В любом случае, рендеринг iPad 2 очень низок.

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

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

Обновить: Примечание. Тень отбрасываемых/измененных изображений добавляется в код. Отключение этого не повлияло на качество масштабирования.

4b9b3361

Ответ 1

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

[imageView.layer setMinificationFilter:kCAFilterTrilinear]

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

Ответ 2

Если вы просто поместите большое изображение в небольшое изображение, это будет выглядеть очень плохо.

решение должно правильно изменить размер изображения... я добавлю примерную функцию, которая выполняет трюк:

- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
    CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
    CGImageRef imageRef = image.CGImage;

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);

    CGContextConcatCTM(context, flipVertical);
    CGContextDrawImage(context, newRect, imageRef);

    CGImageRef newImageRef = CGBitmapContextCreateImage(context);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];

    CGImageRelease(newImageRef);
    UIGraphicsEndImageContext();

    return newImage;
}

эта функция может занять некоторое время.. поэтому вы можете сохранить результат в файл кеша.

Ответ 3

Если вы не боитесь тратить память и знаете, что делаете для конкретного случая, это прекрасно работает.

myView.layer.shouldRasterize = YES;
myView.layer.rasterizationScale = 2;

Полученное качество намного лучше, чем setMinificationFilter.

Я использую изображения размером 256x256 и масштабируя их до примерно 48 px. Очевидно, что более разумным решением было бы уменьшить масштаб изображения до нужного размера.

Ответ 4

Применение небольшого смещения фильтра минимизации может помочь в этом, если вы не хотите сами повторно изменять изображение:

imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.minificationFilterBias = 0.1

введите описание изображения здесь

Левое изображение не имеет фильтрации. Правильное изображение имеет отклонение фильтра 0,1.

Обратите внимание, что явная растеризация не требуется.

Играя с очень маленькими значениями, вы обычно можете получить значение, которое достаточно сглаживает артефакты масштабирования, и это намного проще, чем изменение размера растрового изображения. Конечно, вы теряете детали при увеличении смещения, поэтому значения, даже меньшие 0,1, вероятно, достаточны, хотя все зависит от размера кадра изображения, отображающего изображение.

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

Другим потенциальным преимуществом этой техники, хотя я сам ее не пробовал, является то, что вы можете анимировать minificationFilterBias. Поэтому, если вы собираетесь масштабировать представление изображения довольно много как часть анимации, учитывая также анимирование смещения фильтра от 0.0 до любого небольшого значения, которое вы определили, подходит для уменьшенного размера.

Наконец, как отмечали другие, если ваше исходное изображение очень велико, этот метод не подходит, если его использовать, потому что Core Animation всегда будет поддерживать исходное растровое изображение. Лучше изменить размер изображения, а затем удалить исходное изображение вместо использования mipmapping в большинстве случаев, но для одноразовых или случайных ситуаций, когда ваши изображения будут освобождены достаточно быстро, это нормально.

Ответ 5

Далее помог мне:

imageView.layer.minificationFilter = kCAFilterTrilinear
imageView.layer.shouldRasterize = true
imageView.layer.rasterizationScale = UIScreen.mainScreen().scale

Следить за производительностью, если она используется в списках прокрутки.