Ответ 1
Измените размер изображения на один пиксель и получите его цвет?
img = Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)
Мне нужно знать средний цвет изображения, когда я загружаю его в приложение Ruby on Rails. Можно ли получить среднее значение цвета в HEX или RGB, чтобы использовать этот цвет позже в представлении, отображающем это изображение?
Что-то вроде:
img = Magick::Image.read(path).first
hexVal = img.getHexValue
Измените размер изображения на один пиксель и получите его цвет?
img = Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)
Я не думаю, что вы можете запросить изображение RMagick для его среднего цвета напрямую, но вычислять такую вещь не так сложно.
Я думаю, что самым простым способом было бы извлечь цветную гистограмму, а затем использовать ее для вычисления среднего. Вероятно, вы захотите quantize изображение, хотя вычисление гистограммы для изображения с большим количеством цветов не является дешевым и, вероятно, бессмысленным занятая работа, если вас просто интересует среднее значение:
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
приятен и ясен, а ясность важнее умения.
Вы также можете попробовать и без шага квантования и использовать то, что лучше всего подходит для изображений, с которыми вы работаете.
Я нашел свое решение (здесь), после того как я проверил все возможности, представленные здесь.
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, потому что это pita с ruby (иначе я использовал sprintf для шестнадцатеричного преобразования)
Рассмотрите возможность использования miro gem, который, по-видимому, следует за "mu is too short": https://github.com/jonbuda/miro
В соответствии с @muistooshort - если вся функция квантования делает изображение менее сложным, принимая средние значения цветов пикселей (предполагая) - не будет даже проще, если вы просто квантовали изображение до цвета, например:
img.quantize(1,Magick::RGBColorspace).color_histogram
И просто используйте полученный цвет?