DrewInTheMountains
DrewInTheMountains

Reputation: 166

Make emoji symbols grayscale in UILabel

I would like to use Apple's built-in emoji characters (specifically, several of the smileys, e.g. \ue415) in a UILabel but I would like the emojis to be rendered in grayscale.

I want them to remain characters in the UILabel (either plain text or attributed is fine). I'm not looking for a hybrid image / string solution (which I already have).

Does anyone know how to accomplish this?

Upvotes: 11

Views: 1564

Answers (1)

Brian Trzupek
Brian Trzupek

Reputation: 5390

I know you said you aren't looking for a "hybrid image solution", but I have been chasing this dragon for a while and the best result I could come up with IS a hybrid. Just in case my solution is somehow more helpful on your journey, I am including it here. Good luck!

import UIKit
import QuartzCore

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // the target label to apply the effect to
        let label = UILabel(frame: view.frame)
        // create label text with empji
        label.text = "🍑 HELLO"
        label.textAlignment = .center
        // set to red to further show the greyscale change
        label.textColor = .red
        // calls our extension to get an image of the label
        let image = UIImage.imageWithLabel(label: label)
        // create a tonal filter
        let tonalFilter = CIFilter(name: "CIPhotoEffectTonal")
        // get a CIImage for the filter from the label image
        let imageToBlur = CIImage(cgImage: image.cgImage!)
        // set that image as the input for the filter
        tonalFilter?.setValue(imageToBlur, forKey: kCIInputImageKey)
        // get the resultant image from the filter
        let outputImage: CIImage? = tonalFilter?.outputImage
        // create an image view to show the result
        let tonalImageView = UIImageView(frame: view.frame)
        // set the image from the filter into the new view
        tonalImageView.image = UIImage(ciImage: outputImage ?? CIImage())
        // add the view to our hierarchy
        view.addSubview(tonalImageView)
    }
}

extension UIImage {
    class func imageWithLabel(label: UILabel) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
        label.layer.render(in: UIGraphicsGetCurrentContext()!)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
}

Upvotes: 4

Related Questions