I need to know the average color from an image when I upload it to my Ruby on Rails application. Is it possible to get the average color value in HEX or in RGB to use this color later in the view that's going to display this image?
当我将图片上传到Ruby on Rails应用程序时,我需要知道图片的平均颜色。是否有可能得到十六进制或RGB的平均颜色值,以便稍后在显示图像的视图中使用这种颜色?
Something like:
喜欢的东西:
img = Magick::Image.read(path).first
hexVal = img.getHexValue
5 个解决方案
#1
21
Resize the image to one pixel and get its color?
将图像的大小调整为一个像素,得到它的颜色?
img = Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)
#2
19
I don't think you can ask an RMagick image for its average color directly but computing such a thing isn't that difficult.
我不认为你可以直接问一个RMagick的图像它的平均颜色,但是计算这样一个东西并不难。
I think the easiest way would be to extract the color histogram and then use that to compute your average. You'd probably want to quantize the image first though, computing the histogram for an image with a lot of colors is not cheap and probably pointless busy work if you're just interested in an average:
我认为最简单的方法是提取颜色直方图然后用它来计算平均值。你可能想先量化图像,如果你只对平均值感兴趣的话,计算一个有很多颜色的图像的直方图并不便宜,而且可能毫无意义。
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 }
That'll give you the average color in avg
. But, the color will be in ImageMagick's internal format (i.e. the components will range from zero to Magick::QuantumRange
) so you'll have to scale them down to 0-255:
这将给出avg的平均颜色。但是,该颜色将采用ImageMagick的内部格式(即组件的范围从0到Magick: QuantumRange),因此必须将它们缩小到0-255:
[:r, :g, :b].each { |comp| avg[comp] = (avg[comp] / Magick::QuantumRange * 255).to_i }
And finally you have the RGB components in avg
as integers between zero and 255 and getting the average color in hex format should be trivial. You could easily merge this into the averaging step if desired.
最后,avg中的RGB组件是0到255之间的整数,得到十六进制格式的平均颜色应该很简单。如果需要的话,可以很容易地将其合并到平均步骤中。
I could probably be cleverer with the iterators but .each
is nice and clear and clarity is more important than cleverness.
我可能会比迭代器更聪明,但每一个都很清晰,清晰比聪明更重要。
You can also try with and without the quantization step and use whichever one works best for the images that you're working with.
您还可以尝试使用量化步骤,也可以不使用量化步骤,使用最适合您使用的图像。
#3
3
I found my solution (here), after I tested all the possibilities presented here.
在我测试了这里提供的所有可能性之后,我找到了我的解决方案(这里)。
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
I hope this helps. I added the conversion to hex color by rmagick, because it's a pita with ruby ( otherwise I used sprintf to hex conversion)
我希望这可以帮助。我添加了rmagick对十六进制颜色的转换,因为它是一个带有ruby的pita(否则我使用sprintf进行十六进制转换)
#4
1
Consider using the miro gem, which seems to follow "mu is too short"'s approach: https://github.com/jonbuda/miro
考虑使用miro gem,它似乎遵循“mu is too short”的方法:https://github.com/jonbuda/miro
#5
1
According to @muistooshort - If all the quantize function does is make a image less complex by taking averages of pixel colors (assuming) - wouldn't be even simpler if you just quantized the image down to color like:
根据@muistooshort——如果所有的量子化函数都是通过使用像素颜色的平均值(假设)使图像不那么复杂的话,如果你只是将图像量化为:
img.quantize(1,Magick::RGBColorspace).color_histogram
And just use the resulting color?
用得到的颜色?
#1
21
Resize the image to one pixel and get its color?
将图像的大小调整为一个像素,得到它的颜色?
img = Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)
#2
19
I don't think you can ask an RMagick image for its average color directly but computing such a thing isn't that difficult.
我不认为你可以直接问一个RMagick的图像它的平均颜色,但是计算这样一个东西并不难。
I think the easiest way would be to extract the color histogram and then use that to compute your average. You'd probably want to quantize the image first though, computing the histogram for an image with a lot of colors is not cheap and probably pointless busy work if you're just interested in an average:
我认为最简单的方法是提取颜色直方图然后用它来计算平均值。你可能想先量化图像,如果你只对平均值感兴趣的话,计算一个有很多颜色的图像的直方图并不便宜,而且可能毫无意义。
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 }
That'll give you the average color in avg
. But, the color will be in ImageMagick's internal format (i.e. the components will range from zero to Magick::QuantumRange
) so you'll have to scale them down to 0-255:
这将给出avg的平均颜色。但是,该颜色将采用ImageMagick的内部格式(即组件的范围从0到Magick: QuantumRange),因此必须将它们缩小到0-255:
[:r, :g, :b].each { |comp| avg[comp] = (avg[comp] / Magick::QuantumRange * 255).to_i }
And finally you have the RGB components in avg
as integers between zero and 255 and getting the average color in hex format should be trivial. You could easily merge this into the averaging step if desired.
最后,avg中的RGB组件是0到255之间的整数,得到十六进制格式的平均颜色应该很简单。如果需要的话,可以很容易地将其合并到平均步骤中。
I could probably be cleverer with the iterators but .each
is nice and clear and clarity is more important than cleverness.
我可能会比迭代器更聪明,但每一个都很清晰,清晰比聪明更重要。
You can also try with and without the quantization step and use whichever one works best for the images that you're working with.
您还可以尝试使用量化步骤,也可以不使用量化步骤,使用最适合您使用的图像。
#3
3
I found my solution (here), after I tested all the possibilities presented here.
在我测试了这里提供的所有可能性之后,我找到了我的解决方案(这里)。
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
I hope this helps. I added the conversion to hex color by rmagick, because it's a pita with ruby ( otherwise I used sprintf to hex conversion)
我希望这可以帮助。我添加了rmagick对十六进制颜色的转换,因为它是一个带有ruby的pita(否则我使用sprintf进行十六进制转换)
#4
1
Consider using the miro gem, which seems to follow "mu is too short"'s approach: https://github.com/jonbuda/miro
考虑使用miro gem,它似乎遵循“mu is too short”的方法:https://github.com/jonbuda/miro
#5
1
According to @muistooshort - If all the quantize function does is make a image less complex by taking averages of pixel colors (assuming) - wouldn't be even simpler if you just quantized the image down to color like:
根据@muistooshort——如果所有的量子化函数都是通过使用像素颜色的平均值(假设)使图像不那么复杂的话,如果你只是将图像量化为:
img.quantize(1,Magick::RGBColorspace).color_histogram
And just use the resulting color?
用得到的颜色?