Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving the hex code of the color of a given pixel

Tags:

minimagick

I have used resize_to_fill down to a [1,1] size thus reducing the image to a single pixel containing what is basically the average color of the entire image (provided the image does not have a huge disparity between height and width, of course). Now I'm attempting to retrieve the color of this single pixel in hex format.

From the terminal window I am able to run the convert command like this:

convert image.png txt:
# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (154,135,116) #9A8774 rgb(154,135,116)

I am however uncertain of how I could run this command from inside the application during the before_save section of the model that the image belongs to. The image is uploaded and attached using carrierwave

So far I have retrieved the image:

image = MiniMagick::Image.read(File.open(self.image.path))

But I'm not quite certain how to procede from here.

like image 860
ken-guru Avatar asked Dec 16 '22 05:12

ken-guru


2 Answers

You could add a pixel_at method like this:

module MiniMagick
  class Image
    def pixel_at(x, y)
      case run_command("convert", "#{escaped_path}[1x1+#{x}+#{y}]", "-depth 8", "txt:").split("\n")[1]
      when /^0,0:.*(#[\da-fA-F]{6}).*$/ then $1
      else nil
      end
    end
  end
end

And then use it like this:

i = MiniMagick::Image.open("/path/to/image.png")
puts i.pixel_at(100, 100)

Outputs:

#34555B
like image 108
Mattias Wadman Avatar answered Jun 09 '23 11:06

Mattias Wadman


For recent versions of MiniMagick change escaped_path to path like this:

module MiniMagick
  class Image
    def pixel_at x, y
      run_command("convert", "#{path}[1x1+#{x.to_i}+#{y.to_i}]", 'txt:').split("\n").each do |line|
        return $1 if /^0,0:.*(#[0-9a-fA-F]+)/.match(line)
      end
      nil
    end
  end
end
like image 29
Peter Avatar answered Jun 09 '23 10:06

Peter