require 'RMagick' require 'open-uri' require 'rexml/document' include REXML class WI def initialize() @url = "http://rorbuilder.info/r/colour_lookup.xml?passthru=1" end def colour(image_file_name) iod = Magick::Image.read(image_file_name).first rows = iod.rows cols = iod.columns doc = Document.new(open(@url, "UserAgent" => "Ruby-ColourLookup reader").read) html_colours = doc.root.elements.to_a("records/colour") a = html_colours.map do |c| [c.text('hexcode'), [c.text('name'), c.text('rgb').split(',').map {|x| x.to_i}]] end name_lookup = Hash[*a.inject([]){|r,x| r + x}] lookup = html_colours.map do |x| [x.text('hexcode'), x.text('rgb').split(',').map {|x| x.to_i}] end rows.times do |y| pixels = iod.get_pixels(0, y, cols, 1) colour_pixels = pixels.map do |c| [c.red, c.green, c.blue].map{|x| "%02x" % Math.sqrt(x).to_i.to_s}.join end pcolours = colour_pixels.map do |x| nhexcode = nearest(x, lookup) ncolour = name_lookup[nhexcode] [x.upcase, nhexcode, *ncolour] end pixels.each_with_index do |x, i| x.red, x.green, x.blue = pcolours[i].last.map {|v| v ** 2} end iod.store_pixels(0, y, cols, 1, pixels) puts '... ' + y.to_s end iod.write 'pixels.jpg' end def hex_decimal(s) s.scan(/../).map{|x| ("%2d" % "0x#{x}").to_i} end def nearest(original_colour, possible_colours=[]) cr, cg, cb = hex_decimal(original_colour) k = possible_colours.map do |hexcode, rgb| r, g, b = rgb [hexcode, (cr - r).abs + (cg - g).abs + (cb - b).abs] end h = Hash[*k.flatten] h.min {|a,b| a[1] <=> b[1]}[0] end end if __FILE__ == $0 wi = WI.new wi.colour('sample.jpg') end
接着,来看下效果。
处理前:
处理后: