iosswiftuicifilter

SwiftUI - CIEdgeWork Filter Returns Blank Image


I'm trying to apply the CIEdgeWork filter in a SwiftUI project, but I'm getting a blank (white) image instead of the expected effect. Here is my implementation:

Code:

import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins

struct EdgeWorkDemo: View {
    let context = CIContext()

    var body: some View {
        VStack {
            if let outputImage = applyEdgeWorkFilter() {
                Image(uiImage: outputImage)
                    .resizable()
                    .scaledToFit()
            } else {
                Text("No Image")
            }
        }
    }

    func applyEdgeWorkFilter() -> UIImage? {
        guard let inputImage = UIImage(named: "imgBG") else {
            print("❌ Image not found")
            return nil
        }
        guard let ciImage = CIImage(image: inputImage) else {
            print("❌ Failed to create CIImage")
            return nil
        }

        let edgeWorkFilter = CIFilter.edgeWork()
        edgeWorkFilter.inputImage = ciImage
        edgeWorkFilter.radius = 40 // area of effect

        guard let resultImage = edgeWorkFilter.outputImage else {
            print("❌ Filter output is nil")
            return nil
        }

        let context = CIContext()
        if let cgImage = context.createCGImage(resultImage, from: resultImage.extent) {
            return UIImage(cgImage: cgImage)
        }

        print("❌ Failed to create CGImage")
        return nil
    }
}

struct EdgeWorkDemo_Previews: PreviewProvider {
    static var previews: some View {
        EdgeWorkDemo()
    }
}

What I've Tried:

Expected Behavior: I expect the CIEdgeWork filter to extract edges from the image, similar to how it's described in the documentation: Apple Docs - CIEdgeWork.

Question:

this is the image i processing using this

My Image


Solution

  • The CIEdgeWork filter actually produces an image that is white where the edges are and transparent otherwise. So when you show that on a white background, you won't see anything. If you switch your device to dark mode, you will see the edge image.

    Alternatively, you can add another filter to the chain that will blend your edges as black on white like this:

    guard let edgeImage = edgeWorkFilter.outputImage else {
        print("❌ Filter output is nil")
        return nil
    }
    
    let blendFilter = CIFilter.blendWithMask()
    blendFilter.inputImage = CIImage(color: .black) // foreground = edges
    blendFilter.backgroundImage = CIImage(color: .white)
    blendFilter.maskImage = edgeImage
    
    guard let resultImage = blendFilter.outputImage?.cropped(to: edgeImage.extent) else {
        print("❌ Filter output is nil")
        return nil
    }