使用SwiftUI对图像进行下采样

时间:2020-09-09 03:16:41

标签: swift swiftui downsampling

我正在显示从网络下载的应用程序中的图像,但我想对其进行降采样,以免它们占用多个MB的内存。我以前可以使用UIKit轻松做到这一点:

php artisan config:clear

还有其他方法,但是它们都依赖于了解图像视图的所需大小,这在SwiftUI中并不简单。

是否存在专门用于对SwiftUI图像进行下采样的良好API /方法?

2 个答案:

答案 0 :(得分:0)

此方法使用CIFilter缩小UIImage

https://developer.apple.com/library/archive/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CILanczosScaleTransform

public extension UIImage {
    func downsampled(by reductionAmount: Float) -> UIImage? {

        let image = UIKit.CIImage(image: self)
        guard let lanczosFilter = CIFilter(name: "CILanczosScaleTransform") else { return nil }
        lanczosFilter.setValue(image, forKey: kCIInputImageKey)
        lanczosFilter.setValue(NSNumber.init(value: reductionAmount), forKey: kCIInputScaleKey)

        guard let outputImage = lanczosFilter.outputImage else { return nil }
        let context = CIContext(options: [CIContextOption.useSoftwareRenderer: false])
        guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil}
        let scaledImage = UIImage(cgImage: cgImage)

        return scaledImage
    }
}

然后您可以在SwiftUI视图中使用

struct ContentView: View {
    var body: some View {
        if let uiImage = UIImage(named: "sample")?.downsampled(by: 0.3) {
            Image(uiImage: uiImage)
        }
    }
}

答案 1 :(得分:0)

我最终用几何读取器解决了这个问题,这并不理想,因为它会使布局有些混乱。

@State var image: UIImage
var body: some View {
   GeometryReader { geo in
       Image(uiImage: self.image)
           .resizable()
           .aspectRatio(contentMode: .fit)
           .onAppear {
               let imageFrame = CGRect(x: 0, y: 0, width: geo.size.width, height: geo.size.height)
               self.downsize(frame: imageFrame) // call whatever downsizing function you want
           }
      }
}

使用几何代理来确定图像的帧,然后下采样到该帧。我希望SwiftUI为此拥有自己的API。