iOS - 基于设备的不同图像或缩放相同的图像?

Posted

技术标签:

【中文标题】iOS - 基于设备的不同图像或缩放相同的图像?【英文标题】:iOS - Different images based on device OR scaling the same image? 【发布时间】:2015-02-26 00:52:19 【问题描述】:

似乎开发人员总是为不同的设备创建不同的图像资产,并根据设备加载它们。但是,为最大分辨率的设备 (iPad) 创建图像,然后为 iPhone 6、5 等缩小该图像是否有任何缺点?

我使用 SpriteKit,所以我只需要创建不同大小的 SKSpriteNode,然后将相同的纹理应用到它们,然后缩放以适应节点。

我知道可以考虑性能(为旧设备加载大图像)。但除此之外,还有别的吗?这些图像会显得更加像素化/模糊吗?

【问题讨论】:

您可以将所有图像创建为 3 倍,然后从那里缩小。例如,150x150 = 3x、100x100 = 2x、50x50 = 1x。除非您要处理数百个图像(例如序列),否则缩小规模并没有那么大的工作量,但结果会显示出来。 【参考方案1】:

完美/纯粹的答案是为每个设备分辨率使用单独的图像和代码。

但是,从您自己的时间和理智的角度来看,使用有限的设置是有意义的,因为分辨率和屏幕尺寸的数量不会很快减少。那么为什么要浪费时间准备多个图像,除非 xcode 之类的东西可以更简单地做到这一点。

对于正方形或固定宽高比的图像,我认为您只需要一张图像。对于像背景这样的图像存在问题,无论分辨率如何,您都需要至少满足不同的宽高比:所以单独的宽高比图像是必不可少的(如 3:2 和 16:9),除非您不介意挤压、拉伸或裁剪图像。

如果您在测试中发现性能受到影响,您可以随时添加较低分辨率的图像。

就像素化而言,这是你无法避免的。如果您考虑从 x3 到 x1 分辨率时会发生什么,您必须将 3x3 像素混合为 1x1。在高分辨率下,任何一个像素宽(如一条线)或在几个像素上具有快速颜色变化的东西都会受到最大影响。网上有很多关于这方面的文章,你可以看看。

避免像素化的唯一方法是使用矢量图像,但这需要特殊的软件来加载矢量图像并将它们渲染到 UIImages 中。

按比例缩小时,每张图片都会受到不同程度的影响。一个想法可能是使用 x2 图像,iPhone 3 将其缩小 1,iPhone 6+ 将其放大 1 至 x3。这将覆盖当前大多数原始分辨率的设备,并且可能提供不太明显的像素化。

【讨论】:

那么你为什么说完美的答案是使用单独的图像?如果我们谈论的是具有相同纵横比的设计,并且按比例缩小图像并没有视觉质量方面的缺点,并且需要更少的代码和更少的物理内存空间......那为什么不这样做呢? 也许我的措辞具有误导性。我以为我说过可以使用高分辨率图像。第一句话暗示了一个纯粹的答案是什么,即为您的问题所建议的每个分辨率和完美性能进行编码。然而,我的观点与文中所述相同,因为它可以节省时间和精力,但您只需要确保处理需要不同纵横比的图像:例如,iPhone 6 的背景不会完美缩小到 iPhone 4,因为一个是 3:2,另一个是 19:6,没有失真或裁剪。【参考方案2】:

这取决于。如果截断图像会带来问题,那么使用一张图像或每个纵横比一张图像当然更经济。

对于像照片这样的图像,这可能是完全可以接受的,因为这种图像往往不包含像素完美的特征。

但是,如果我们正在处理图形艺术品 - 细线、清晰的轮廓、像素完美的特征 - 缩放可能会严重损害质量。

考虑以下示例:假设您想创建一个具有固定大小的自定义文本字段。文本区域由线宽为 1px 的黑色轮廓包围。您正在为您的作品使用视网膜分辨率,并且您的起点是 4" 屏幕尺寸。如果文本字段与屏幕一起缩放,该框将如何显示在其他屏幕尺寸上?它在非屏幕上的外观如何? -视网膜显示?

非视网膜:分辨率需要减半。想象一下你的作品中有一个 2x2 像素的块——它需要被计算成一个像素。我们的轮廓只有 1px 的宽度,所以一个 2x2 像素块和一条线穿过它包含两个黑色和两个白色像素。生成的非视网膜像素将为灰色。实际上,缩放会稍微复杂一些,但结果会是模糊、黑色较少且线条稍粗。

Scaled Retina:需要提高分辨率。想象一个分辨率为 4" 屏幕的 1.5 倍的设备。1px 线需要变成 1.5 像素宽,这显然是行不通的。相反,原来的 1px 线将被拉伸成灰度两个(或更多)像素,近似于 1.5 像素线的“黑度”。

无论哪种方式(向上或向下)缩放都会使轮廓模糊、更粗且黑色更少。

这个例子并不是一个完美的例子,因为 ios 允许定义具有完美缩放的可拉伸部分的图像。对于我们的矩形框,这实际上是可能的。但它不适用于更复杂的艺术品。

如果像素完美是必须的,那么就没有办法解决每种分辨率的图像或矢量图形 (Quartz / SVGKit / ...)

编辑:我在 Photoshop 中使用双线性缩放复制了我的示例。它在设备上可能看起来略有不同,因为它可能使用另一种缩放算法。但我想你会明白的......

【讨论】:

【参考方案3】:

我有一段时间的印象是,您以后可以缩放的单个图像也可以。

有关执行此操作的多种方法以及一些基准,请查看NSHispter: Image Resizing Techniques

如需进一步阅读,请查看Core Image Apple 文档,NSHipster 文章也提到了该文档。

【讨论】:

【参考方案4】:

实际上没有人回答图像质量是否会降低。我刚刚尝试实现这一点,与保持原始尺寸相比,图像确实显得稍微像素化。

【讨论】:

用像素化的想法更新了我的答案。【参考方案5】:

我可以根据我在内存使用方面的经验来回答。关于图像质量的问题已经有足够多的人回答了,所以唯一的另一个问题是内存使用问题。我使用了您在我的游戏 Piston Flip 中描述的技术,它运行良好,因为我没有使用很多纹理或节点。然而,在我正在开发的另一个使用图块的游戏中,我无法使用大图像并缩小它们,因为每个设备几乎只能处理加载为其屏幕尺寸指定的图块。

所以这真的取决于。

【讨论】:

以上是关于iOS - 基于设备的不同图像或缩放相同的图像?的主要内容,如果未能解决你的问题,请参考以下文章

IOS 8 图像缩放和自动布局

iOS UIScrollView捏缩放添加空白

图像映射在 iOS 设备上不起作用,大图像会被设备重新缩放

iOS Xcode 使背景图像缩放以填充

UIView 高度无法跨设备正确缩放图像

iOS5 中的图像移动和缩放问题