This was asked a long time ago, but I ran into it myself, and found that the following does work:
swift4
import CoreImage
import CoreImage.CIFilterBuiltins
func getCheckWithColor(color: CIColor) - UIImage {
let baseImage = UIImage(named: "CheckWhite.png")!
let bgImage = CIImage(image: baseImage)
let colorImage = CIImage(color)
let filter = CIFilter.multiplyCompositing()
filter.backgroundImage = bgImage
filter.inputImage = colorImage
let multiplied = filter.outputImage!
return UIImage(ciImage: multiplied).resizableImage(withCapInsets: .zero, resizingMode: .stretch)
}
The above example does the same thing as:
swift4
let baseImage = UIImage(named: "CheckWhite.png")!
return baseImage.withTintColor(CIColor(red: 0.8, green: 0.4, blue: 0.8, alpha: 0.75), renderingMode: .automatic).resizableImage(withCapInsets: .zero, resizingMode: .stretch)
After which I use it like such:
swift4
let checkImageView = UIImageView(image: finalImage)
checkImageView.contentMode = .scaleToFill
checkImageView.frame = checkFrame
(So that was a fairly trivial example but of course you can do many more operations with CIFilter than just the UIImage withTintColor method. It's lovely that we don't have to enter strings into CIFilter anymore, in 2021.)
More generally, it seems that whether or not you need to render the image into a context or not (as per the original question) depends on the CIImage's extent (i.e. kind of like a CGImage's rect).
If it's an infinite extent, or DOUBLE_MAX, then you cannot simply convert to a UIImage. That's because CIImage aren't always actual images. As you can notice from the example, colorImage is an infinite image with a particular color.
So to answer the poster's question, it can be done. You need to check the extent property of the CIImage.