Skip to content

Instantly share code, notes, and snippets.

@branch14
Created February 8, 2014 21:30
Show Gist options
  • Save branch14/8890671 to your computer and use it in GitHub Desktop.
Save branch14/8890671 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
require 'optparse'
require 'ostruct'
require 'RMagick'
include Magick
# ------------------------------------------------------------
resolution = {
# ------------------------------
# --- 3:4 digital
'10x13' => [ 800, 1000],
'11x15' => [ 894, 1200],
'13x17' => [1000, 1350],
'15x20' => [1200, 1600],
'20x27' => [1600, 2200],
'30x40' => [2400, 3150],
# ------------------------------
# --- 2:3 classic
'9x13' => [ 700, 1000],
'10x15' => [ 800, 1200],
'13x18' => [1000, 1450],
'20x30' => [1600, 2400],
'30x45' => [2400, 3600],
# ------------------------------
# --- 2:3 classic inch
'4x6i' => [ 800, 1200]
}
# ------------------------------------------------------------
options = OpenStruct.new
options.density = '200x200'
options.filename_pattern = "%02dx%02d.jpg"
opts = OptionParser.new do |o|
o.on('-x', '--num-x X', 'Number of shots on the x-axis') { |x| options.x = x }
o.on('-y', '--num-y Y', 'Number of shots on the y-ayis') { |y| options.y = y }
o.on('-i', '--image FILENAME', 'The image to operate on') { |i| options.filename = i }
o.on('-p', '--preview PREVIEW', 'Render preview') { |p| options.preview = p }
o.on('-f', "--filter 'FILTER'", 'Apply filter, e.g.: gaussian_blur(0, 3)') { |f| options.filter = f }
o.on('-s', "--size SIZE", 'Size of paper') { |s| options.size = s }
end
opts.parse!(ARGV)
# ------------------------------------------------------------
ox = options.x.to_f
oy = options.y.to_f
puts "output image tiles: % 6d x % 6d" % [ox, oy]
tpx = resolution[options.size][1]
tpy = resolution[options.size][0]
puts "size of ouput tile: % 6d x % 6d" % [tpx, tpy]
opx = ox * tpx
opy = oy * tpy
puts "size of ouput image: % 6d x % 6d" % [opx, opy]
puts "reading image ..."
img = Image.read(options.filename)[0]
ipx = img.columns
ipy = img.rows
puts "size of input image: % 6d x % 6d" % [ipx, ipy]
if options.preview
puts "preview mode ..."
scale = opx / options.preview.to_f
ppx = opx / scale
ppy = opy / scale
puts "size of preview image: % 6d x % 6d, scaling factor: %f" % [ppx, ppy, scale]
puts "generating preview ..."
preview = Magick::Image.new(ppx, ppy) { self.background_color = 'white'}
puts "resizing image for preview ..."
pimg = img.resize_to_fit(ppx, ppy)
puts "compositing ..."
preview.composite!(pimg, CenterGravity, OverCompositeOp)
puts "drawing lines ..."
d = Draw.new
d.stroke_color('black')
d.fill_opacity(0)
for y in 0..oy-1
d.line(0, y * ppy / oy, ppx, y * ppy / oy)
end
for x in 0..ox-1
d.line(x * ppx / ox, 0, x * ppx / ox, ppy)
end
d.draw(preview)
puts "writing preview ..."
preview.write('preview.jpg')
puts "done."
exit
end
puts "finishing mode ..."
car = (tpx * ox) / (tpy * oy)
cpx, cpy = ipx, ipy
cpy = cpx * car if cpy < cpx * car
cpx = cpy / car if cpx < cpy / car
puts "size of canvas: % 6d x % 6d" % [cpx, cpy]
puts "generating canvas ..."
canvas = Magick::Image.new(cpx, cpy) { self.background_color = 'white' }
puts "compositing ..."
o = canvas.composite(img, CenterGravity, OverCompositeOp)
tpx = cpx / ox
tpy = cpy / oy
puts "cutting canvas into tiles ..."
for y in 0..oy-1
for x in 0..ox-1
filename = options.filename_pattern % [x + 1, y + 1]
puts "generating #{filename}"
nimg = o.crop(tpx * x, tpy * y, tpx, tpy)
nimg.density = options.density
nimg.sample!(tpx, tpy)
if options.filter
puts "applying filter: #{options.filter}"
eval "nimg = nimg.#{options.filter}"
end
nimg.write(filename)
end
end
exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment