Search code examples
avfoundationavcapturesessioncifilteravcaptureavcapturevideodataoutput

Output of CIFilter has different effect for different sizes of same image


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

I have two output:

  • AVCaptureVideoDataOutput for preview
  • AVCapturePhotoOutput for save photo in hightResolution.

After applied filters I get different results.


Solution

  • This happens because most parameters of built-in Core Image filters operate on a pixel basis. In your case it's the inputRadius parameter of the CICrystallize filter. From the docs:

    The radius determines how many pixels are used to create the effect. The larger the radius, the larger the resulting crystals.

    That means that you need to set the parameter to different values depending on the input size.

    I usually calculate some kind of factor that I multiply with my base parameter value. For instance:

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