Cool Effects with Core Image!
In a previous article I described how to use Core Image as the backend image processor for Attachment Fu in your Rails applications. In that particular article we looked at supporting image scaling and thumbnails to be compatible with the other Attachment Fu backends such as RMagick and ImageScience.
With Core Image available however, we have an entire range of post processing filters available to use at our fingertips. In this article we’ll step through a few of these additional filter options that you can use to post process your images with.
Here’s a few examples of what we can do with Core Image post file upload. All of the following examples use the following input image taken in Berlin while at RailsConf EU (also used in the performance measurements article):

Greyscale or Sepia
A scaled version of the source image is cool, but how about an automatic greyscale or sepia version of the image:
Greyscale

Sepia

Code Fragment
module RedArtisan module CoreImage module Filters module Color def greyscale(color = nil, intensity = 1.00) create_core_image_context(@original.extent.size.width, @original.extent.size.height) color = OSX::CIColor.colorWithString("1.0 1.0 1.0 1.0") unless color @original.color_monochrome :inputColor => color, :inputIntensity => intensity do |greyscale| @target = greyscale end end def sepia(intensity = 1.00) create_core_image_context(@original.extent.size.width, @original.extent.size.height) @original.sepia_tone :inputIntensity => intensity do |sepia| @target = sepia end end end end end end
Exposure and Noise Control
Another option for us is to automatically adjust exposure and noise parameters upon upload to brighten images up, or remove unwanted noise from lower quality images:
1 F-Stop

2 F-Stops

Noise Removal

Code Fragment
module RedArtisan module CoreImage module Filters module Quality def reduce_noise(level = 0.02, sharpness = 0.4) create_core_image_context(@original.extent.size.width, @original.extent.size.height) @original.noise_reduction :inputNoiseLevel => level, :inputSharpness => sharpness do |noise_reduced| @target = noise_reduced end end def adjust_exposure(input_ev = 0.5) create_core_image_context(@original.extent.size.width, @original.extent.size.height) @original.exposure_adjust :inputEV => input_ev do |adjusted| @target = adjusted end end end end end end
Watermarking
Sometimes we’d like to automatically add a watermark to our images, either with a single watermark image, or as a tiled watermark image:
Single Watermark

Tiled Watermark

Code Fragment
module RedArtisan module CoreImage module Filters module Watermark def watermark(watermark_image, tile = false, strength = 0.1) create_core_image_context(@original.extent.size.width, @original.extent.size.height) if watermark_image.respond_to? :to_str watermark_image = OSX::CIImage.from(watermark_image.to_str) end if tile tile_transform = OSX::NSAffineTransform.transform tile_transform.scaleXBy_yBy 1.0, 1.0 watermark_image.affine_tile :inputTransform => tile_transform do |tiled| tiled.crop :inputRectangle => vector(0, 0, @original.extent.size.width, @original.extent.size.height) do |tiled_watermark| watermark_image = tiled_watermark end end end @original.dissolve_transition :inputTargetImage => watermark_image, :inputTime => strength do |watermarked| @target = watermarked end end end end end end
Funky Effects
We can also use cool and funky effects used in applications like Photobooth, here’s an example using the edge colouring algorithm:
Edges

Core Fragment
module RedArtisan module CoreImage module Filters module Effects def edges(intensity = 1.00) create_core_image_context(@original.extent.size.width, @original.extent.size.height) @original.edges :inputIntensity => intensity do |edged| @target = edged end end end end end end
The sign artwork works particularly well with this algorithm.
Core Image Processor
All of the code above is also available as a usable image processor via git.
Some examples of using the processor:
require 'red_artisan/core_image/processor' # generate some test output images for various effects processor = RedArtisan::CoreImage::Processor.new('berlin.jpg') grey = processor.greyscale grey.save 'results/berlin-grey.jpg' sepia = processor.sepia sepia.save 'results/berlin-sepia.jpg' watermarked = processor.watermark('watermark_image.png') watermarked.save 'results/berlin-watermarked.jpg' watermarked = processor.watermark('watermark_image.png', true) watermarked.save 'results/berlin-watermarked-tiled.jpg' noise_reduced = processor.reduce_noise noise_reduced.save 'results/berlin-noise-reduced.jpg' exposure_adjusted = processor.adjust_exposure exposure_adjusted.save 'results/berlin-exposure-adjusted-half-stop.jpg' exposure_adjusted = processor.adjust_exposure(2.0) exposure_adjusted.save 'results/berlin-exposure-adjusted-two-stops.jpg' edge = processor.edges edge.save 'results/berlin-edge.jpg'
Summary
The above shows us only a fraction of what can be done with the 100+ filters Core Image provides by default. There’s many other filters that let you create all sorts of effects with single and multiple images combined. Enjoy!

