Ruby
ImageMagick
MiniMagick

MiniMagickで画像から支配色を抽出

RMagickでメモリ消費しまくるので、MiniMagickに切り替えてみた(結果的には、あまり変わらなかったけど)。

この時に、画像中で使用頻度の高い支配色を抽出するロジックも書き直したのでメモ。戻すカラースタイルは今回HSL形式。

path = '/path/to/image'
img = MiniMagick::Image.open(path)
quantity = 5
threshold = 0.01

result = img.run_command(
  'convert', path,
  '-format', '%c',
  '-colors', quantity,
  '-depth', 8,
  '-colorspace', 'HSL',
  'histogram:info:'
)

frequencies = result.scan(/([0-9]+)\:/).flatten.map(&:to_f)
hsl_values = result.scan(/ hsl\((\d+)%,(\d+)%,(\d+)%\)/).map do |hsl|
  { h: 360 * hsl[0].to_i / 100, s: hsl[1].to_i, l: hsl[2].to_i }
end
total_frequencies = frequencies.reduce(:+).to_f

frequencies
  .map.with_index { |frequency, index| [frequency / total_frequencies, hsl_values[index]] }
  .sort           { |r| r[0] }
  .select         { |r| r[0] > threshold }
  .map            { |r| r[1] }
  .slice(0, quantity)