Можно ли получить средний цвет изображения с помощью RMagick? - PullRequest
13 голосов
/ 02 марта 2011

Мне нужно знать средний цвет изображения, когда я загружаю его в свое приложение Ruby on Rails. Можно ли получить среднее значение цвета в HEX или RGB, чтобы использовать этот цвет позже в представлении, которое будет отображать это изображение?

Что-то вроде:

img =  Magick::Image.read(path).first
hexVal = img.getHexValue

Ответы [ 5 ]

22 голосов
/ 02 марта 2011

Изменить размер изображения до одного пикселя и получить его цвет?

img =  Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)
19 голосов
/ 02 марта 2011

Не думаю, что вы можете напрямую запросить изображение RMagick для его среднего цвета, но вычислить такую ​​вещь не так уж и сложно.

Я думаю, что самый простой способ - это извлечь цветгистограмма , а затем используйте ее для вычисления среднего значения.Возможно, вы сначала захотите квантовать изображение, хотя вычисление гистограммы для изображения с большим количеством цветов не дешево и, вероятно, бессмысленная занятая работа, если вы просто заинтересованы в среднем:

total = 0
avg   = { :r => 0.0, :g => 0.0, :b => 0.0 }
img.quantize.color_histogram.each { |c, n|
    avg[:r] += n * c.red
    avg[:g] += n * c.green
    avg[:b] += n * c.blue
    total   += n
}
[:r, :g, :b].each { |comp| avg[comp] /= total }

Это даст вам средний цвет в avg.Но цвет будет во внутреннем формате ImageMagick (т. Е. Компоненты будут в диапазоне от нуля до Magick::QuantumRange), поэтому вам придется уменьшить их до 0-255:

[:r, :g, :b].each { |comp| avg[comp] = (avg[comp] / Magick::QuantumRange * 255).to_i }

И, наконец, у вас естькомпоненты RGB в avg в виде целых чисел от нуля до 255 и получение среднего цвета в шестнадцатеричном формате должны быть тривиальными.При желании вы могли бы легко объединить это с шагом усреднения.

Возможно, я мог бы быть умнее с итераторами, но .each хорош и ясен, а ясность важнее, чем ум.

Вы можететакже попробуйте с шагом и без шага квантования и используйте тот, который лучше всего подходит для изображений, с которыми вы работаете.

3 голосов
/ 28 января 2014

Я нашел свое решение ( здесь ) после того, как проверил все представленные здесь возможности.

def maincolor()
  img =  Magick::Image.read(self.url).first
  pix = img.scale(1, 1)
  avg_color_hex = pix.to_color(pix.pixel_color(0,0))
  return avg_color_hex
end

Надеюсь, это поможет.Я добавил преобразование в шестнадцатеричный цвет с помощью rmagick, потому что это пита с рубином (в противном случае я использовал преобразование sprintf в шестнадцатеричный)

1 голос
/ 29 апреля 2013

Согласно @muistooshort - если все, что делает функция квантования, - это сделать изображение менее сложным, принимая средние цвета пикселей (при условии) - было бы еще проще, если бы вы просто квантовали изображение до цвета, подобного:

img.quantize(1,Magick::RGBColorspace).color_histogram

А просто использовать полученный цвет?

1 голос
/ 27 февраля 2012

Подумайте об использовании миро-драгоценного камня, который, похоже, следует подходу "mu is too short": https://github.com/jonbuda/miro

...