SwiftUI:控制图像插值
如果您创建一个SwiftUI Image
视图以将其内容拉伸到大于其原始大小,会发生什么?默认情况下,我们获得图像插值,这是iOS平滑混合像素的地方,您甚至可能根本没有意识到它们已经被拉伸了。当然,这需要付出一定的性能代价,但是大多数时候都不用担心。
但是,在某个地方,图像插值会引起问题,那就是在处理精确像素时。例如,该项目在GitHub上的文件包含一个名为example@3x.png 的卡通外星人小图像——取自 Kenney Platform Art Deluxe 资源包,网址为 https://kenney.nl/assets/platformer-art-deluxe,可在公共领域使用。
![](https://img.haomeiwen.com/i2955252/5bf2173d37ff2fb0.png)
继续并将该图形添加到资产目录中,然后将ContentView
结构更改为此:
Image("example")
.resizable()
.scaledToFit()
.frame(maxHeight: .infinity)
.background(Color.black)
.edgesIgnoringSafeArea(.all)
这样会将外来字符呈现在黑色背景上,以使其更易于查看,并且由于可调整大小,SwiftUI会将其拉伸以填充所有可用空间。
![](https://img.haomeiwen.com/i2955252/0b1f9ab61d4b77d1.png)
仔细观察颜色的边缘:它们看起来参差不齐,但也模糊。锯齿状的部分来自原始图像,因为它的尺寸仅为66x92像素,但是模糊的部分是SwiftUI试图在拉伸像素时对其进行融合以使拉伸不那么明显的地方。
通常,这种混合效果很好,但是在这里却很难解决,因为源图片很小(因此需要大量混合然后才能以我们想要的尺寸显示),并且图像中有很多纯色,因此混合像素显得突出很明显。
对于这种情况,SwiftUI为我们提供了interpolation()
修饰符,使我们可以控制像素融合的应用方式。这有多个层次,但实际上,我们只关心一个层次:.none
。这将完全关闭图像插值,因此,与其混合像素,不如将它们放大而具有锐利的边缘。
因此,将您的图像修改为此:
Image("example")
.interpolation(.none)
.resizable()
.scaledToFit()
.frame(maxHeight: .infinity)
.background(Color.black)
.edgesIgnoringSafeArea(.all)
![](https://img.haomeiwen.com/i2955252/f96e679218915ee5.png)
现在,您将看到外来角色保留了像素化外观,这不仅在复古游戏中特别流行,而且对于线条艺术(在模糊时看起来会出错)也很重要。