Search code examples
iosswiftcore-imagecgimageciimage

How to add text to CIImage?


I am working with the Photos framework and have created an app that will apply a filter to an image. Now instead of applying a filter, I want to add text on top of the image. This API provides me with a CIImage which I can use to create an output CIImage. I just do not know how to add text at a specific location to a CIImage. If I am correct, it would not be recommended to convert it to a CGImage and then add the text due to performance degradation.

How could one work with an existing CIImage to output that exact same CIImage (preserve original image quality) with text laid on top at a specific location?

//Get full image
let url = contentEditingInput.fullSizeImageURL
let orientation = contentEditingInput.fullSizeImageOrientation
var inputImage = CIImage(contentsOfURL: url)
inputImage = inputImage.imageByApplyingOrientation(orientation)

//TODO: REPLACE WITH TEXT OVERLAY
/*//Add filter
let filterName = "CISepiaTone"
let filter = CIFilter(name: filterName)
filter.setDefaults()
filter.setValue(inputImage, forKey: kCIInputImageKey)
let outputImage: CIImage = filter.outputImage*/

//Create editing output
let jpegData: NSData = self.jpegRepresentationOfImage(outputImage)
let adjustmentData = PHAdjustmentData(formatIdentifier: AdjustmentFormatIdentifier, formatVersion: "1.0", data: filterName.dataUsingEncoding(NSUTF8StringEncoding))

let contentEditingOutput = PHContentEditingOutput(contentEditingInput: contentEditingInput)
jpegData.writeToURL(contentEditingOutput.renderedContentURL, atomically: true)
contentEditingOutput.adjustmentData = adjustmentData

PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
    let request = PHAssetChangeRequest(forAsset: asset)
request.contentEditingOutput = contentEditingOutput
}, completionHandler: { (success: Bool, error: NSError!) -> Void in
    if !success {
        NSLog("Error saving image: %@", error)
    }
})

Solution

  • You could draw the text in grayscale into a separate CGImage, convert the CGImage into a CIImage (via [+CIImage imageWithCGImage:]) and then use it as a mask, sending it and the original CIImage to the CIBlendWithMask filter.