使用RMagick可以获取图像的平均颜色吗?

13
我需要知道上传到我的Ruby on Rails应用程序的图像的平均颜色。是否可以获取十六进制或RGB格式的平均颜色值,以便稍后在显示该图像的视图中使用此颜色?类似于:

Something like:

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

正如我在你的使用JavaScript相关问题中所问的:“你只想要精确的像素颜色,还是在特定的HSV范围内?(我建议后者会更好地为您服务。)” - Phrogz
6个回答

23

将图像调整为一个像素并获取其颜色?

img =  Magick::Image.read(path).first
pix = img.scale(1, 1)
averageColor = pix.pixel_color(0,0)

1
一个(非常)快速的测试表明,这比使用“color_histogram”要快得多。 - joost
1
真是聪明的解决方案!+1 - bodacious
我们得到了一个“Magick :: Pixel”对象,但如果我们想要以十六进制格式获得RGB,“就像CSS使用的那样(例如#f0a1b2)”,我们该怎么做? tingel2k在下面回答了这个问题。 - Aleksandrus

19
我认为你无法直接询问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 }
最后,您将在 avg 中得到介于零和255之间的整数的RGB分量,以十六进制格式获取平均颜色应该很容易。如果需要,您可以轻松地将其合并到平均步骤中。
我可能可以使用迭代器更聪明,但.each很清晰,清晰比聪明更重要。
您还可以尝试有和没有量化步骤,并使用对您正在处理的图像最有效的那个。

7
那篇博客的日期是2011年7月5日,我的回答发布于2011年3月2日。 - mu is too short
1
如果量化函数所做的只是通过取像素颜色的平均值使图像变得不那么复杂(假设如此)- 那么将图像量化为颜色是否更简单? - sfkaos
@sfkaos:我猜你评论中缺失的部分是关于将图像量化为一种颜色。这可能有效,我猜它会产生与stef's“将其缩小到一个像素”的方法相同的效果。但我不确定底层算法对调色板会产生什么影响,我想运行一些测试来查看真实图像的情况。不过这是个好主意。 - mu is too short

3

我在这里找到了解决方案 (链接),在尝试本文中提及的所有可能性后。

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的十六进制颜色转换,因为使用ruby实现十六进制转换较为麻烦(否则我会使用sprintf进行十六进制转换)


不幸的是,这种方法有时会返回无效的十六进制颜色。例如:"#AAC5C3F1"。 - rikas
嗯...我不确定。我怎么知道呢?或者我怎么转换这个图像? - rikas
1
嗨,请阅读此处 -> https://github.com/rmagick/rmagick/blob/master/examples/identify.rb,您可以获取有关颜色通道深度的信息。 - tingel2k

1
根据@muistooshort的说法,如果量化功能只是通过取像素颜色的平均值来使图像变得更简单(假设如此),那么将图像量化为颜色会更简单:
img.quantize(1,Magick::RGBColorspace).color_histogram

"只使用生成的颜色吗?"

1

0

1
请不要仅仅将某个工具或库作为答案发布。至少在答案中演示它是如何解决问题的。 - Yunnosch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接