Search code examples
rubyimage-processingcolorsimagemagickchunkypng

How to modify the color of images to remove vibrancy?


How I can change the colors from this:

enter image description here

into this:

enter image description here

I generated the output image using Gimp with the input image as layer one, and the background color from the image as layer two, in the Layers panel I selected the mode "colors"

I want preserve the background color, but want the colors be shades of brown.

Any ideas to do this with ChunkyPNG? Or should I use ImageMagick with color lookup tables?


Solution

  • Thanks for your ideas.

    I found the one from Linuxios the most helpful Gimp layer modes

    require "json"
    require "httpclient"
    require "chunky_png"
    
    module ChunkyPNG::Color
    
      def h(value)
        r,g,b = r(value).to_f / MAX, g(value).to_f / MAX, b(value).to_f / MAX
        min, max = [r,g,b].minmax
    
        return 0 if max == min
    
        result = case max
          when r then (g - b) / (max - min) + (g < b ? 6 : 0)
          when g then (b - r) / (max - min) + 2
          when b then (r - g) / (max - min) + 4
        end
    
        result * 60
      end
    
      def s(value)
        min, max = [r(value), g(value), b(value)].minmax.map { |value| value.to_f / MAX }
        max == 0 ? 0 : (max - min) / max
      end
    
      def v(value)
        [r(value), g(value), b(value)].max.to_f / MAX
      end
    
      def hsv(h, s, v)
        h = h.to_f / 360
        i = (h * 6).floor
        f = h * 6 - i
        p = v * (1 - s)
        q = v * (1 - f * s)
        t = v * (1 - (1 - f) * s)
    
         case i % 6
          when 0 then r, g, b = v, t, p
          when 1 then r, g, b = q, v, p
          when 2 then r, g, b = p, v, t
          when 3 then r, g, b = p, q, v
          when 4 then r, g, b = t, p, v
          when 5 then r, g, b = v, p, q
        end
    
        rgb *[r,g,b].map {|value| (value * 255).round }
      end
    
    end
    
    
    module CoderWall
    
      module_function
    
      def badges(username)
        url = URI.escape("https://coderwall.com/#{username}.json")
        response = HTTPClient.get(url)
    
        json = JSON.parse(response.body)
        urls = json['badges'].map {|b| b['badge']}
        brown      = ChunkyPNG::Color.from_hex("#bf8a30")
        hue        = ChunkyPNG::Color.h(brown)
        saturation = ChunkyPNG::Color.s(brown)
        value      = ChunkyPNG::Color.v(brown)
        urls.each do |url|
          matches = url.match /(\w+)\-/
          response = HTTPClient.get(url)
          filename = "./tmp/coderwall/"+matches[1]+".png"
          File.open(filename,"w") {|f| f.write(response.body)}
    
          image = ChunkyPNG::Image.from_file(filename)
    
          image.pixels.map! do |pixel|
              v = ChunkyPNG::Color.v(pixel)
              unless ChunkyPNG::Color.a(pixel) > 0
                v = value
              end
              ChunkyPNG::Color.hsv(hue,saturation, v)
          end
          image.save(filename.gsub(/\.png/,"_brown.png"), :fast_rgba)
        end
      end
    end
    
    badges = CoderWall.badges("astropanic")
    

    That above code consists from some snippets found around the web.

    Here is the result: Stop doing new year resolutions. Make the change now !