CIFilter的输出对于同一张图片不同尺寸有不同的效果

问题描述 投票:0回答:2
func getImageWithFilter(by filterType: MainViewModel.FilterType,
    image: CIImage) -> CIImage {

    guard filterType.filterEnabled,
        let filter = CIFilter(name: filterType.rawValue)
    else {
        return image
    }
    filter.setValue(image, forKey: kCIInputImageKey)

    return filter.outputImage ?? image
}

enter image description here enter image description here

我有两个输出:

  • AVCaptureVideoDataOutput 用于预览
  • AVCapturePhotoOutput 用于以高分辨率保存照片。

应用过滤器后,我得到不同的结果。

avfoundation avcapturesession cifilter avcapture avcapturevideodataoutput
2个回答
3
投票

发生这种情况是因为内置 Core Image 滤镜的大多数参数都是以像素为基础进行操作的。在您的情况下,它是

inputRadius
过滤器的
CICrystallize
参数。来自文档:

半径决定了使用多少像素来创建效果。半径越大,产生的晶体就越大。

这意味着您需要根据输入大小将参数设置为不同的值。

我通常会计算某种与基本参数值相乘的因子。例如:

let inputSizeFactor = min(inputImage.size.width, inputImage.size.height) / 1000
let scaledRadius = radius * inputSizeFactor
filter.setValue(scaledRadius, forKey: "inputRadius")

0
投票

正如@FrankRupprecht 提到的,

发生这种情况是因为内置 Core Image 过滤器的大多数参数 以像素为基础进行操作。在你的情况下,它是 inputRadius 参数 CICrystalize 过滤器的。

为了获得相同的输出,我通常采用直观的方法。

  1. 第一步: 应用

    CIAffineClamp
    滤镜,使您的图像无限延伸。请参阅 cifilter.io/CIAffineClamp/

  2. 第二步: 应用任何过滤器,例如

    CICrystallize, CIComicEffect, CIGaussianBlur...

  3. 最后一步: 根据源图像延伸裁剪图像

    let outputImage = sourceImage // Step 1
            .applyingFilter("CIAffineClamp", parameters: [
                "inputTransform": CGAffineTransform.identity
            ])
            .applyingFilter("CIGaussianBlur") // Step 2
    
    guard let outputImage = filter.outputImage,
          let cgImage = contex.createCGImage(outputImage, from: sourceImage.extent) // Final Step
    let uiImage = UIImage(cgImage: cgImage)
    
© www.soinside.com 2019 - 2024. All rights reserved.