如何使用 UIImageView 的内容模式 UIViewContentModeScaleAspectFit 保持高度不变来避免丢失图像质量?

Posted

技术标签:

【中文标题】如何使用 UIImageView 的内容模式 UIViewContentModeScaleAspectFit 保持高度不变来避免丢失图像质量?【英文标题】:How to avoid losing image quality using UIImageView's contentmode UIViewContentModeScaleAspectFit keeping height constant? 【发布时间】:2016-12-20 05:58:07 【问题描述】:

我在tableview 中使用collectionview 来显示异步下载的图像。我需要做的是在不挤压的情况下展示这些图像。我保持collectionview 的高度不变,并在下载图像后计算它们的大小。我保持UIIamgeView UIViewContentModeScaleAspectFit 的内容模式。这就是我为实现预期结果所做的工作。

- (void)configureMediaCell:(MediaContainerViewCell *)weakCell withMediaItem:(MSZWallPostMedia *)mediaItem withDownloadImage:(UIImage *)image
    if (mediaItem.isFrameSet == NO) 
        weakCell.isFrameSet = YES;
        weakCell.cellImageView.image = image;
        weakCell.cellImageView.contentMode = UIViewContentModeScaleAspectFit;
        CGRect frame = weakCell.cellImageView.frame;

        //Image Scaling
        CGSize scaleSize = [self imageScale:weakCell.cellImageView];

        scaleSize.width = scaleSize.width * image.size.width;
        scaleSize.height = scaleSize.height * image.size.height;
        frame.size.width = scaleSize.width;
        frame.size.height = scaleSize.height;
        weakCell.cellImageView.frame = frame;
        mediaItem.frame = frame;
        mediaItem.isFrameSet = YES;
        [weakCell.activityIndicatorView stopAnimating];
        [self.collectionView reloadItemsAtIndexPaths:@[weakCell.indexPath]];
     else 
        [weakCell.activityIndicatorView stopAnimating];
        weakCell.cellImageView.image = image;
        weakCell.cellImageView.frame = mediaItem.frame;
        weakCell.cellImageView.contentMode = UIViewContentModeScaleAspectFit;
    

对于图像缩放:

- (CGSize)imageScale : (UIImageView *)imageView 
    CGFloat sx = imageView.frame.size.width / imageView.image.size.width;
    CGFloat sy = imageView.frame.size.height / imageView.image.size.height;
    CGFloat s = 1.0;
    switch (imageView.contentMode) 
        case UIViewContentModeScaleAspectFit:
            s = fminf(sx, sy);
            return CGSizeMake(s, s);
            break;

        case UIViewContentModeScaleAspectFill:
            s = fmaxf(sx, sy);
            return CGSizeMake(s, s);
            break;

        case UIViewContentModeScaleToFill:
            return CGSizeMake(sx, sy);

        default:
            return CGSizeMake(s, s);
    

这种方法的问题是我得到了正确的宽度和高度,但有些图像显示得更小,这很明显,因为我使用的是附加屏幕中显示的 imageview 的Aspectfit 属性。

对此的任何帮助将不胜感激。我需要保留图像,因为它们保持collectionviewitem 的高度固定和可变宽度。

【问题讨论】:

【参考方案1】:

如果我理解正确的话。您只需要找到图像的宽高比并乘以所需的高度。

示例:

图片

宽度 = 30,高度 = 10

单元格

宽度 = ?, 高度 = 7

比率 = 30 / 10

单元格宽度 = 7 * (30/10) = 21

单元格大小将变为 (21,7)

希望这就是你的意思。但是如果图像小于单元格,您将面临问题。然后它可能会变形。

【讨论】:

以上是关于如何使用 UIImageView 的内容模式 UIViewContentModeScaleAspectFit 保持高度不变来避免丢失图像质量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在“方面填充”模式下将 UIImageView 裁剪为新的 UIImage?

如何在“方面填充”模式下将 UIImageView 裁剪为新的 UIImage?

UIImageView:如何在平移和缩放后仅捕获可见内容

UIImageView 内容模式和比例因子

无法使用 uiimageview 同时满足 uitableviewcell 中的约束

UIImageView + UIImage vs CALayer + 内容效率