Image Blend Modes

July 2nd, 2008

You can use various Photoshop-style blend modes to composite two or more images by applying the “blend” method to an Image object.

#!/usr/local/bin/macruby

require 'hotcocoa/graphics'
include HotCocoa
include Graphics

# set up the canvas and font
canvas = Canvas.new :type => :image, :filename => 'blend.png', :size => [400,730]
canvas.background(Color.white)
canvas.font('Skia')
canvas.fontsize(14)

# set image width,height
w,h = [95,95]

# set initial drawing position
x,y = [0,canvas.height - h - 10]

# load and resize two images
imgA = Image.new('v2.jpg').resize(w,h)
imgB = Image.new('italy.jpg').resize(w,h)

# add image B to image A using each blending mode, and draw to canvas
for blendmode in [:normal,:multiply,:screen,:overlay,:darken,:lighten,
  :colordodge,:colorburn,:softlight,:hardlight,:difference,:exclusion,
  :hue,:saturation,:color,:luminosity,:maximum,:minimum,:add,:atop,
  :in,:out,:over] do
  imgA.reset.resize(w,h)
  imgA.blend(imgB, blendmode)
  canvas.draw(imgA,x,y)
  canvas.text(blendmode,x,y-15)
  x += w + 5
  if (x > canvas.width - w + 5)
    x = 0
    y -= h + 25
  end
end

canvas.save

Gradients

June 30th, 2008

Radial or linear gradients may be drawn by first specifying their main constituent colors, then applying to the canvas with a start and endpoint. (warning: crashes in MacRuby 0.4)

#!/usr/local/bin/macruby

framework 'cocoa'
require 'rubygems'
require 'hotcocoa/graphics'
include HotCocoa
include Graphics

# FIXME: SEGFAULT!!

# set up the canvas and font
canvas = Canvas.new :type => :image, :filename => 'gradients.png', :size => [400,400]
canvas.background(Color.black)

# create a new gradient
gradient = Gradient.new

# set the component colors of the gradient
gradient.set(Color.black,Color.blue,Color.red.darken,Color.orange)

# draw a linear gradient starting at 50,50 and ending at 200,200
canvas.gradient(gradient, 50,50,200,200)

# do not extend gradient beyond its start/endpoints
gradient.pre(false)
gradient.post(false)

# draw a radial gradient starting at 200,200 with radius 100
canvas.radial(gradient, 200,200,100)

# save the canvas
canvas.save

Image Color Parsing

June 30th, 2008

You can load an image, grab an array of colors from it, and then apply those colors to other objects on the canvas.

#!/usr/local/bin/macruby

framework 'cocoa'
require 'rubygems'
require 'hotcocoa/graphics'
include HotCocoa
include Graphics

# set up the canvas and font
canvas = Canvas.new :type => :image, :filename => 'parsing.png', :size => [400,400]
canvas.background(Color.black)
canvas.shadow

# load an image and select 100 random colors
image = Image.new('italy.jpg')
randomcolors = image.colors(100)

# create a 20x20 square at 0,0
square = Path.new.rect(0,0,20,20,:center)

# randomize the color, scale, and rotation of the square
square.randomize(:fill, randomcolors)
square.randomize(:scale, 1.0..5.0)
square.randomize(:rotation, 0..360)

# draw 100 squares and the original image
canvas.grid(square,10,10)
image.fit(120,120)
canvas.draw(image)
canvas.save

Color Harmony Schemes

June 29th, 2008


Various sets of colors can be generated from a single starting color by using the various classical color harmony schemes.  For more information, see Color Theory on Wikipedia.

#!/usr/local/bin/macruby

framework 'cocoa'
require 'rubygems'
require 'hotcocoa/graphics'
include HotCocoa
include Graphics

# set up the canvas and font
canvas = Canvas.new :type => :image, :filename => 'harmony.png', :size => [400,400]
canvas.background(Color.white)
canvas.font('Skia')
canvas.fontsize(12)

# create a new color with the specified red, green, blue, and alpha values
blue = Color.new(0.0,0.4,0.6,1.0)

# draw the original color
canvas.translate(135,350)
canvas.text("original color",-115,10)
canvas.fill(blue)
canvas.rect(0,0,255,30)
canvas.fill(Color.black)

# create a rectangle to use as a color swatch
swatch = Path.new.rect(0,0,15,30)
swatch.increment(:x, 15)

# draw harmony schemes derived from this color
for scheme in [
  :complementary,:split_complementary,:left_complement,
  :right_complement,:monochrome,:triad,:tetrad,:compound,
  :flipped_compound
  ] do
  canvas.translate(0,-38)
  canvas.text(scheme,-115,10)
  swatch.increment(:fill, blue.send(scheme).sort)
  canvas.draw(swatch,0,0,17)
end

# save the canvas
canvas.save