Xcode @2x 图像后缀在 iOS 中未显示为 Retina

Posted

技术标签:

【中文标题】Xcode @2x 图像后缀在 iOS 中未显示为 Retina【英文标题】:Xcode @2x image suffix not showing as Retina in iOS 【发布时间】:2019-04-25 16:41:43 【问题描述】:

我在处理视网膜图像时遇到问题。

下面的屏幕截图显示了UICollectionView,每个UICollectionViewCell 中都包含一个UIImageView

在应用程序中,我有一个名为 travel.png 的 512x512 像素的大图像。 当我将此文件命名为 travel.png 时,绿色圆圈显示了应用程序上显示的内容。蓝色圆圈显示了当我将图像名称更新为 travel@2x.png(即视网膜命名)时看到的内容。

我希望由于图像尺寸较大 (512x512),只需添加 @2x 后缀就足以将其转换为定义的两倍(即视网膜),但正如您从两个屏幕截图中看到的那样,两个版本图像显示为非视网膜。

如何更新图像以使其显示在 Retina 中?

旅行.png:

旅行@2x.png: * 更新 * 以下 cmets 中的以下请求:

我通过调用以下函数加载此图像:

// Note - when this method is called: contentMode is set to .scaleAspectFit & imageName is "travel"
public func setImageName(imageName: String, contentMode: ContentMode) 

    self.contentMode = contentMode
    if let image = UIImage(named: imageName) 
        self.image = image
            

这是图像在应用渲染之前在 Xcode 中的显示方式(您可以看到它的清晰度足够高):

【问题讨论】:

如何加载图像进行显示?您也可以将图像本身发布到某个地方吗?如果图像看起来像那样锯齿状,重命名它不会神奇地平滑它。 @matt - 感谢您的请求。我在自定义 ImageView 类中添加了设置图像的方法,并提供了图像在 xcode 中的外观(相当高的清晰度)。 也许考虑创建一个小示例代码来显示这个问题。然后检查出什么问题会更容易 如果图像视图的尺寸远小于图像尺寸(从屏幕截图中看起来是这样),您是否尝试过使用较小尺寸的图像?有时,即使“缩小尺寸”,图像也会像素化。因此,它足以使用在正确的 2x 尺寸下看起来非常清晰且非像素化的图像资源,即对于 80x80 uiimageview,2x 分辨率图像的尺寸只需要在 160x160 像素左右。 “真的很想弄清楚如何将高清添加到我现有的应用程序中。”但不够热衷于制作演示项目来展示您正在做的事情。 【参考方案1】:

您看到低质量图像的原因是anti-aliasing。当您提供的图像大于 UIImageView 的实际框架(scaleAspectFit 模式)时,系统将自动缩小它们。在缩放期间,可以在曲线形状处添加一些抗锯齿效果。为避免这种影响,您应该提供要在屏幕上显示的确切图像尺寸。

要检测 UIImageView 是否自动缩放图像,您可以在 Simulator 菜单中打开 Debug->Color Misaligned Images:

现在所有缩放的图像都会在模拟器上以黄色突出显示。每个突出显示的图像都可能存在抗锯齿伪影并影响缩放算法的 CPU 使用率:

要解决此问题,您应该使用精确的尺寸。因此系统将直接使用它们,无需任何额外的计算。例如,如果您的按钮大小为 80x80px,您应该添加三个图像来断言目录,其尺寸和 dpi 如下:80x80px (72 dpi)、160x160px (144 dpi) 和 240x240px (216 dpi):

现在图像将在屏幕上绘制而无需缩小,视觉质量要好得多:

【讨论】:

【参考方案2】:

如果您的意图是只为所有尺寸提供一张图片,我建议您使用Assets.xcassets。在这里创建文件夹结构和管理媒体资产很容易。

步骤

    单击+ 图标时,您将显示操作列表。选择创建New folder。 选择新建的文件夹,再次点击+图标,然后点击New Image Set。 选择图像集。并选择属性检查器。 在Scales 下选择Single Scale。 拖放图片。 根据需要重命名图像名称和文件夹名称。 现在,您可以使用所有屏幕尺寸的图像名称来使用此图像。

【讨论】:

【参考方案3】:

TL;DR;

将视图层的minificationFilter更改为.trilinear

imageView.layer.minificationFilter = .trilinear

如下面的设备截图所示

正如 Anton 的回答正确指出的那样,您观察到的锯齿效应是由源图像与其显示的图像视图之间的巨大尺寸差异引起的。如果您不添加 @2x 后缀,则不会改变任何内容更改源图像本身的尺寸。

也就是说,有一种简单的方法可以在不调整原始图像大小的情况下改善这种情况:CALayer 提供了对图形后端用于调整图像大小的方法的一些控制:minificationFiltermagnificationFilter。第一个与您的情况相关,因为图像尺寸正在减小。默认值为CALayerContentsFilter.linear,只需切换到.trilinear 以获得更好的结果(更多信息请参见those wikipedia pages)。这将需要更多的 GPU 功率(因此需要电池),尤其是当您将其应用于许多图像时。

您真的应该考虑在显示图像之前调整它们的大小,无论是静态的还是在运行时(并且可能缓存调整大小的版本)。除了糟糕的视觉质量之外,在 UI 中大量使用如此大的图像会降低性能并浪费大量内存,从而可能导致其他问题。

【讨论】:

【参考方案4】:

我已经修复了@DarshanKunjadiya 问题。 确保(如果您已经在使用资产):

    确保图像未被分配 现在在情节提要或代码中使用图像,无需扩展。 (例如“图像”而不是“图像.png”)

如果您不使用资产中的图像,请将它们移至资产。

Demo Projects

希望对您有所帮助。 让我知道您的反馈。

【讨论】:

【参考方案5】:

我认为没有@2x@3x 的图像是为低分辨率设备(如iphone 4 和3G)呈现的。 我认为的解决方案是始终使用.xcassets 文件或在图像名称中添加@2x or @3X

【讨论】:

【参考方案6】:

ios 中,内容基于 iOS 坐标系放置在屏幕上。为了在具有 1:1 像素密度的标准分辨率系统上显示图像,我们应该以@1x 分辨率提供图像。对于更高分辨率的显示器,像素密度将是 2.0、3.0 的比例因子,在 iOS 系统中分别称为 @2x 和 @3x。也就是说,高分辨率显示器需要更高密度的图像。

例如,如果您想以标准分辨率显示尺寸为 128x128 的图像。您必须提供相同的@2x 和@3x 尺寸图像。即,@2x 版本为 256x256,@3x 版本为 384x384 图像。

在下面的截图中,我为 2x 版本提供了一个 256x256 大小的图像,以便在 iPhone 6s 中显示一个 128x128 像素的图像。 iPhone 6s 以@2x 大小渲染图像。使用带有资产目录的 1x、2x 和 3x 三个版本的图像将解决您的问题。所以 iPhone 会根据屏幕分辨率自动渲染正确大小的图像。

【讨论】:

请阅读以下链接以了解有关 iPhone 显示高分辨率图像的人机界面指南的更多信息。 developer.apple.com/design/human-interface-guidelines/ios/… 1.我认为从问题中可以清楚地看出,关于 2x 和 3x 如何工作的一般信息并不是预期的。 2.在您回答的示例中(128x128 为 1x),3x 大小将是 384x384 而不是 512x512。 @SwapnilLuktuke 对不起,我错误地输入了 512x512

以上是关于Xcode @2x 图像后缀在 iOS 中未显示为 Retina的主要内容,如果未能解决你的问题,请参考以下文章

@2x 图像不显示在 XCode4 界面构建器设计器中

使用 Xcode 10 在 Watch Simulator 中未显示资产目录图像?

背景图像在 Safari 和 iOS 中未显示全宽

使用 Xcode 的 iOS 应用程序中未显示按钮和标签

使用 Sketch 3 的 iOS 图像分辨率大小

iOS 14 升级中未加载 react-native 图像