| 
          # ------------------------------------------------------------ | 
        
        
           | 
          # 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 ) } |