Core Imageを最適化するには

Updated
Mar 9, 2021 4:18 AM
Created
Mar 9, 2021 3:39 AM
Tags
CoreImage
Keywords

フィルターのパラメータが変わるたびにCIFilterを作り直すことはよく無いかと思ったが、大したパフォーマンスへの影響はなさそう。

Memo Code
final class HardwareImageViewController : UIViewController {

  @IBOutlet weak var slider: UISlider!
  @IBOutlet weak var imageConatinerView: UIView!

  let imageView: UIView & HardwareImageViewType = {
    #if canImport(MetalKit) && !targetEnvironment(simulator)
    return MetalImageView()
    #else
    return GLImageView()
    #endif
  }()

  let image: CIImage = {
    return CIImage(image: UIImage(named: "large")!)!
      .transformed(by: .init(scaleX: 0.5, y: 0.5))
      .insertingIntermediate(cache: true)
  }()
  
  let filter = CIFilter(
    name: "CIGaussianBlur",
    parameters: [:]
  )
  
  var outputImage: CIImage?

  override func viewDidLoad() {
    super.viewDidLoad()

    imageConatinerView.addSubview(imageView)
    imageView.frame = imageConatinerView.bounds
    imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    filter?.setValue(image.clamped(to: image.extent), forKey: kCIInputImageKey)
    
    outputImage = filter?.outputImage
//    filter?.setValue(image, forKey: kCIInputImageKey)

  }

  @IBAction func didChangeSliderValue(_ sender: Any) {
    
    let value = slider.value

    #if true
    filter?.setValue(Double(value * 50), forKey: "inputRadius")
//    print(filter?.outputImage, outputImage)
    let result = filter?.outputImage?.cropped(to: image.extent)
    imageView.display(image: result)
    #else
    let result = HardwareImageViewController.makeBlur(image: image, radius: Double(value * 50))!
    imageView.display(image: result)
    #endif
  }

  static func makeBlur(image: CIImage, radius: Double) -> CIImage? {
    

    let outputImage = image
      .clamped(to: image.extent)
      .applyingFilter(
        "CIGaussianBlur",
        parameters: [
          "inputRadius" : radius
        ])
      .cropped(to: image.extent)

    return outputImage
  }
}

AppleによるCoreImageのベストプラクティス

☝️

User smaller images when possible. Performance scales with the number of output pixels. You can have Core Image render into a smaller view, texture, or framebuffer. Allow Core Animation to upscale to display size. Use Core Graphics or Image I/O functions to crop or downsample, such as the functions CGImageCreateWithImageInRect or CGImageSourceCreateThumbnailAtIndex.