Skip to content

Instantly share code, notes, and snippets.

@Telmo
Forked from briangonzalez/README.md
Created October 21, 2012 06:51
Show Gist options
  • Save Telmo/3926180 to your computer and use it in GitHub Desktop.
Save Telmo/3926180 to your computer and use it in GitHub Desktop.
img2boxshadow - a ruby script to convert images to CSS [http://codepen.io/briangonzalez/details/AvrGI#pen-details-tab]

img2boxshadow.rb

a ruby script to convert images to CSS (box-shadows)

Installation

gem install rmagick    # you'll need ImageMagick & Ruby first
gem install colormath
gem install micro-optparse

Usage

How to run the script:

ruby img2boxshadow.rb -i <input> -o <output>

For large images, it's best to use an emulated pixel size, which takes n amount of pixels and blends them into one. Your output will be much smaller, but resolution will be lower. The following will combine a 4x4 pixel square into one box shadow statement.

ruby img2boxshadow.rb -i <input> -o <output> -p 4

The demo on CodePen uses the following settings:

ruby img2boxshadow.rb -i img/woman_small.jpeg -o output.css -p 5 -s 3 -b 1 -g '#000'

Options:

-p, --pixel-size 2               emulated pixel size
-s, --pixel-spacing -1           pixel spacing
-b, --blur 0                     pixel blur
-g, --background white           background color
-i, --input                      input file
-o, --output                     output css
-h, --help                       Show this message
-v, --version                    Print version
# ------------------------------------------------------------
# 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 ) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment