|
# ------------------------------------------------------------ |
|
# img2boxshadow |
|
# |
|
# © 2012, Brian Gonzalez |
|
# briangonzalez.org |
|
# ------------------------- |
|
|
|
require 'micro-optparse' |
|
require 'rmagick' |
|
require 'colormath' |
|
|
|
options = Parser.new do |p| |
|
p.banner = "\n -- img2boxshadow ----------\n\n" |
|
p.version = "v001" |
|
p.option :pixel_size, "emulated pixel size", :default => 2, :short => 'p' |
|
p.option :pixel_spacing, "pixel spacing", :default => -1, :short => 's' |
|
p.option :blur, "pixel blur", :default => 0, :short => 'b' |
|
p.option :background, "background color", :default => 'white', :short => 'g' |
|
p.option :input, "input file", :default => '', :short => 'i' |
|
p.option :output, "output css", :default => '', :short => 'o' |
|
end.process! |
|
|
|
if (!File.exists? options[:input]) |
|
puts "Input file doesnt exist!" |
|
Kernel.exit(1) |
|
end |
|
|
|
img = Magick::Image::read( options[:input] ).first |
|
puts "\n Processing: #{img.base_filename}..." |
|
puts " Format: #{img.format}" |
|
|
|
width = img.columns |
|
height = img.rows |
|
puts " Geometry: #{width}x#{height}" |
|
|
|
# Iterate over the pixels. |
|
shadows = [] |
|
|
|
pixel_size = options[:pixel_size] |
|
w_pixels = width/pixel_size |
|
h_pixels = height/pixel_size |
|
|
|
pixels = [] |
|
w_pixels.times do |w| |
|
|
|
h_pixels.times do |h| |
|
|
|
x = w*pixel_size |
|
y = h*pixel_size |
|
|
|
group = img.get_pixels(x, y, pixel_size, pixel_size) |
|
|
|
blended_pixel = group.inject do |val, p| |
|
c = ColorMath::RGB.new(p.red.to_f/255, p.green.to_f/255, p.blue.to_f/255) |
|
result = (val.class.name == "Magick::Pixel") ? c : ColorMath::Blend.alpha(val, c, 0.5) |
|
result |
|
end |
|
|
|
if (blended_pixel.class.name == "Magick::Pixel") |
|
shadows << "#{x}px #{y}px #{options[:blur]}px rgb(#{blended_pixel.red},#{blended_pixel.green},#{blended_pixel.blue})" |
|
else |
|
shadows << "#{x}px #{y}px #{options[:blur]}px #{blended_pixel.hex}" |
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
# The HTML |
|
html = " <div id='art'>\n" |
|
html << " <div></div>\n" |
|
html << " </div>\n" |
|
|
|
puts "\n ---------------------------------------" |
|
puts " Your HTML, kind sir:" |
|
puts " ---------------------------------------\n" |
|
puts html |
|
|
|
# The CSS |
|
pixel_spacing = (options[:pixel_spacing] < 0 or options[:pixel_size] > pixel_size) ? pixel_size : options[:pixel_spacing] |
|
|
|
css = "body{ background: #{options[:background]}; }\n\n" |
|
|
|
css << "#art {" |
|
css << " width: #{width+1}px; height: #{height+1}px;" |
|
css << " position: absolute; top: 50%; left: 50%;" |
|
css << " margin-top: -#{height/2}px; margin-left: -#{width/2}px;" |
|
css << "}\n\n" |
|
|
|
css << "#art div{\n" |
|
css << "\twidth: #{pixel_spacing}px;" |
|
css << "height: #{pixel_spacing}px;" |
|
css << "background: transparent;" |
|
css << "box-shadow: #{shadows.map { |s| s }.join(",\n\t")};" |
|
css << "}" |
|
|
|
# Write the CSS file |
|
File.open(options[:output], 'w') {|f| f.write( css ) } |