阅读 209

[SwiftUI 100 天] 在 SwiftUI 中控制图像插值

译自 www.hackingwithswift.com/books/ios-s…

更多内容,欢迎关注公众号 「Swift花园」

喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀

在 SwiftUI 中控制图像插值

在 SwiftUI 中,当你把一个 Image 的内容拉伸到比它原始尺寸更大的大小时会发生什么?默认情况下,我们会得到 图像插值,iOS 很平滑地地混合了像素,你可能都没有意识到它们是被拉伸过的。当然,这个过程有性能开销,但开销多数情况下都可以忽略。

不过,图像插值有一种情况可能导致问题,那就是你在处理精确的像素的时候。举个例子,这个项目在 Github 上的文件包含一张名叫 example@3x.png 的卡通外星人 —— 它是从 Kenney Platform Art Deluxe 的 bundle 里拿来的,公开域名的地址是 kenney.nl/assets/plat…

把这种图片添加到 asset catalog,然后把 ContentView 改成这样:

Image("example")
    .resizable()
    .scaledToFit()
    .frame(maxHeight: .infinity)
    .background(Color.black)
    .edgesIgnoringSafeArea(.all)
复制代码

这份代码会在一个黑色背景上渲染出外星人,SwiftUI 对其进行了拉伸,填满所有可用空间。

近距离观察一下边缘的颜色:不仅有锯齿,而且模糊。锯齿的部分来自原始图像,因为它只有 66x92 像素。而模糊的部分是由于 SwiftUI 为了让拉伸看起来不那么明显,在拉伸像素的同时也混合了像素。

通常这个混合过程可以完美工作,但在这里由于源图片太小,它进行地很艰难(由大量的像素需要混入)。也意味图像有太多的纯色江苏,所以混合的像素也非常突兀。

对于这种情况,SwiftUI 提供了 interpolation() modifier,可以让我们控制像素混合的方式。实际上有很多种方式,但这里我们只关心一种:.none。它会把图像插值关闭,因此不会混合像素,只是保留锋利的边缘放大。

把代码改成下面这样:

Image("example")
    .interpolation(.none)    
    .resizable()
    .scaledToFit()
    .frame(maxHeight: .infinity)
    .background(Color.black)
    .edgesIgnoringSafeArea(.all)
复制代码

这样你就会看到外星人保留了原汁原味的像素风,这在动感游戏里不流行,但在线条艺术里还是很重要的。


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~

Swift花园微信公众号