0

I can display the UIImage that I load but when I convert it to a CIimage and back it fails to display correctly.

struct ContentView: View {
    @State var stateString = "abc";
    @State var stateImage = UIImage(named: "Lenna")
    
    var body: some View {
        VStack {
            Image(uiImage: stateImage!)
            Text(stateString)
        }
        .padding()
        .onAppear(){
            guard let uiimage = UIImage(named: "Lenna") else {return};
            guard let ciimage = CIImage(image: uiimage) else {return};
            
            stateString = "past guard"
            stateImage = UIImage(ciImage: ciimage);
        }
    }
}
P.Bjur
  • 13
  • 4
  • This seems like a completely futile exercise. What's the point? A UIImage in general is _not_ backed by a CIImage and cannot be converted to and from a CIImage. You can usually round-trip between a UIImage and _CGImage_ pretty well, but a CIImage is a completely different sort of thing. – matt Dec 24 '22 at 21:11
  • @matt It is a completely futile exercise. I am just starting to play around with this and wanted to be able to load images as placeholders for what will eventually be images captured by the camera. Is there a better way to get placeholder CIimages besides loading them from the device? – P.Bjur Dec 24 '22 at 21:54
  • CIImages are for use with Core Image. They are not something that is ever displayed so you don't need one as a placeholder. Images captured by the camera are not CIImages either. – matt Dec 24 '22 at 22:03
  • @matt Sorry I was unclear, I am making a utility that will operate on a CIImage. Eventually, these will come directly from the camera. In the mean time I wanted to load images, process them as I would, and then display them. I figured a good starting point would be to make sure that I could convert to a CIImage make no changes and convert it back into a UIImage so that I knew that it would work without me making any changes to CIImage. So this is just a learning exercise. Is there a way for me to imitate an image captured by the camera that I should be using instead? – P.Bjur Dec 24 '22 at 23:12

1 Answers1

1

As Matt says in the comments, this is sort of silly. Are you just doing this as a learning exercise?

I've converted UIImages to CIImages, applied Core Image filters to them, and then converted them back to UIImages (or rather, from CIImage to CGImage to UIImage.)

UIImage is backed by a CGImage, and if you have a UIImage you can get to it's backing CGImage with a property of the UIImage. You can also easily create a UIImage from a CGImage.

CIImage is used by Core Image, which is cross-platform. It interacts with CGImage, not UIImage. You'll need to convert from UIImage to CGImage, and then from CGImage to CIImage.

CIImage has an initializer that takes a CGImage as input:

init(cgImage image: CGImage)

And then in this link there is a function that will convert a CIImage back to a CGImage.

That function (from the link, not my code) looks like this:

func convertCIImageToCGImage(inputImage: CIImage) -> CGImage? {
    let context = CIContext(options: nil)
    if let cgImage = context.createCGImage(inputImage, from: inputImage.extent) {
        return cgImage
    }
    return nil
}
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thanks @Duncan. I am trying to make a utility that will make changes to a image captured by the camera. I wanted to avoid actually capturing the image yet and instead just load the images from device and operate on that. Is there a better way for me to do that than converting from a CGImage to a CIImage? – P.Bjur Dec 24 '22 at 23:15
  • @P.Bjur did you check if your UIImage's `ciImage` property is `nil`? – Leo Dabus Dec 24 '22 at 23:32
  • So you want to initially process images loaded from the user's camera roll and apply core image filters to them? Converting your images from CGImage to CIImage should work fine. – Duncan C Dec 25 '22 at 20:25