Last Updated: February 25, 2016
·
1.159K
· widescape

RubyMotion Tinted Image with CGBlendMode

Inspired by http://robots.thoughtbot.com/designing-for-ios-blending-modes.

class UIImage
  def tintedImageWithColor(tintColor)
    UIGraphicsBeginImageContext(self.size)
    tintColor.setFill
    bounds = [[0, 0], self.size]
    UIRectFill(bounds)
    self.drawInRect(bounds, blendMode: KCGBlendModeHardLight, alpha: 0.8)
    tintedImage = UIImage.UIGraphicsGetImageFromCurrentImageContext
    UIImage.UIGraphicsEndImageContext
    tintedImage
  end
end

Then use it like this:

image = UIImage.imageNamed('image.png')
tinted_image = image.tintedImageWithColor(UIColor.redColor)
view = UIImageView.alloc.initWithImage(tinted_image)

How I go this to work:

The Apple reference on CGContext declares CGBlendModes with a small first letter. In RubyMotion you need to change that to a capital first letter.

# Will raise an error:
self.drawInRect(bounds, blendMode: kCGBlendModeHardLight, alpha: 0.8)
# Will work:
self.drawInRect(bounds, blendMode: KCGBlendModeHardLight, alpha: 0.8)

Additionally, in RubyMotion UIGraphicsEndImageContext and UIGraphicsGetImageFromCurrentImageContext don't work on their own, so it's necessary to prepend UIImage. to them:

# Will raise errors:
tintedImage = UIGraphicsGetImageFromCurrentImageContext
UIGraphicsEndImageContext
# Will work:
tintedImage = UIImage.UIGraphicsGetImageFromCurrentImageContext
UIImage.UIGraphicsEndImageContext

Happy tinting!