簡體   English   中英

對同一圖像的不同尺寸實現相同的 CIFilter 效果

[英]Achieve same CIFilter effect on different sizes of same image

我正在構建一個照片編輯器,為了保持良好的性能,我首先過濾了一個小版本的圖像,當用戶想要導出它時,我過濾了更高分辨率的圖像。

我正在使用 CIGaussianBlur 濾鏡,但對於不同的圖像分辨率,我無法獲得相同的結果。

這是我的代碼:

class ViewController : UIViewController {

var originalImage = UIImage()
var previewImageView = UIImageView()
var previewCIImage: CIImage!
var scaleFactor = CGFloat()

let blurFilter = CIFilter.gaussianBlur()
var blurSlider = UISlider()
var blurRadius = Float()

override func viewDidLoad() {
    previewImageView.image = originalImage.scalePreservingAspectRatio(targetSize: previewImageView.frame.size)
    previewCIImage = CIImage(image: previewImageView.image!)
    
    // Get the scale factor
    scaleFactor = originalImage.getScaleFactor(targetSize: previewImageView.frame.size)
    
    blurSlider.addTarget(self, action: #selector(blurChanged(slider:)), for: .valueChanged)
}

@objc func blurChanged(slider: UISlider) {
    blurRadius = slider.value
    
    let scaledRadius = blurRadius * Float(scaleFactor)
    blurFilter.radius = scaledRadius
    
    MTKView.setNeedsDisplay()
}

func exportFullSizeImage() -> UIImage {
    let inputImage = CIImage(image: originalImage)!
            
    blurFilter.inputImage = inputImage.clampedToExtent()
    
    // Assuming scaleFactor is 1.0 for the unscaled image
    let scaledRadius = blurRadius * 1.0
    blurFilter.radius = scaledRadius

    let output = (blurFilter.outputImage)!
    let outputCGImage = context.createCGImage(output, from: output.extent)
    
    return UIImage(cgImage: outputCGImage!)
}

}

extension UIImage {
func scalePreservingAspectRatio(targetSize: CGSize) -> UIImage {
    let widthRatio = targetSize.width / size.width
    let heightRatio = targetSize.height / size.height
    
    let scaleFactor = min(widthRatio, heightRatio)
            
    let scaledImageSize = CGSize(
        width: size.width * scaleFactor,
        height: size.height * scaleFactor
    )
    
    let renderer = UIGraphicsImageRenderer(
        size: scaledImageSize
    )

    let scaledImage = renderer.image { _ in
        self.draw(in: CGRect(
            origin: .zero,
            size: scaledImageSize
        ))
    }
    return scaledImage
}

func getScaleFactor(targetSize: CGSize) -> CGFloat {
    let widthRatio = targetSize.width / size.width
    let heightRatio = targetSize.height / size.height
    let scaleFactor = min(widthRatio, heightRatio)
    return scaleFactor
}

}

這是圖像的小版本(預覽圖像)的輸出:

在此處輸入圖像描述

這是全尺寸圖像(未縮放圖像)的輸出:

在此處輸入圖像描述

結果明顯不同,全尺寸/未縮放的圖像更加模糊。 我需要在兩個圖像上實現相同的模糊效果。

我發現了兩個類似的問題: CIFilter 的輸出對同一圖像的不同尺寸有不同的效果以及如何在同一圖像的多個尺寸上實現相同的 CIFilter 效果

我知道調整大小圖像的比例因子,這可能有助於獲得答案。

鏈接答案的參數縮放應該適用於所有圖像,無論它們的縱橫比如何。 重要的部分是您將比例因子應用於圖像、預覽導出。

或者,由於您具有調整后圖像的比例因子,您可以使用它來縮放參數(而不是使用圖像大小):

// assuming scaleFactor is 1.0 for the unscaled image
let scaledRadius = radius * scaleFactor 
filter.setValue(scaledRadius, forKey: "inputRadius")

另請注意,並非每個濾鏡的每個參數都需要縮放以實現不同圖像尺寸的一致性。 通常,只有描述某種效果半徑或大小的參數才需要縮放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM