Search code examples
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:

  • Confirmed that "imgBG" is present in the asset catalog.
  • Tried reducing the radius to 5 and 10 but still getting a blank output.
  • Wrapped the image with CIAffineClamp before applying CIEdgeWork to avoid transparent edges.
  • Tested other filters like CISepiaTone, which work correctly.
  • Used different image formats (JPEG, PNG).
  • Ran on both the simulator and a real device.

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:

  • Why is CIEdgeWork returning a blank image?
  • Are there any known limitations with this filter in SwiftUI?
  • Is there an alternative way to achieve a similar effect?

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
    }