2008年12月21日
以前、ハロウィン前に公開して一部の方から好評をいただいた「かぼちゃミク」(初音ミクの髪などの青色をかぼちゃ色にしたもの)。冬至が近いということで、そのときのプログラムをRuby+RMagickに移植したものを公開してみる。
RMagickのインストールは若干面倒なので、多分このあたりを参照すればよいでしょう(私は試していませんが)。
- Windows: RMagickをWindows環境にインストール - Lazy Technology
- LinuxでAPTが使える場合: RMagickをインストール - ゆっくり*ゆっくり
- Linuxでrpm/yumが使える場合: CentOS4.5にRMagickをインストール - プログラマ 福重 伸太朗 〜基本へ帰ろう〜
肝心のコードはこちら。<gist.githubでコードを入手>
require "rubygems"
require "RMagick"
module Magick
class Pixel
def get_hsv
r = red; g = green; b = blue
if r > g
max = ((b > r) ? b : r); min = ((g > b) ? b : g)
else
max = ((b > g) ? b : g); min = ((r > b) ? b : r)
end
# Hue 色相(0-360)
if max == min
# 未定義
h = 0
else
if max == r
h = 60 * (g - b) / (max - min)
elsif max == g
h = 60 * (b - r) / (max - min) + 120
else
h = 60 * (r - g) / (max - min) + 240
end
end
h += 360 if h < 0
# Saturation 彩度(0.0-1.0)
s = ((max == 0) ? 0 : ((max - min)*QuantumRange.to_f/max)/QuantumRange)
# max == 0 のときは未定義
# Value 明度(0.0-1.0) : max/(RGBそれぞれの最大値)に等しい
[h, s, max.to_f/QuantumRange]
end
def Pixel.from_hsv(h, s, v)
range = (h / 60).to_i
diff_h = h - 60 * range
p = (v * (1.0 - s)) * QuantumRange
q = (v * (60 - s * diff_h) / 60) * QuantumRange
t = (v * (60 - s * (60 - diff_h)) / 60) * QuantumRange
v *= QuantumRange
case range
when 0; Pixel.new(v, t, p)
when 1; Pixel.new(q, v, p)
when 2; Pixel.new(p, v, t)
when 3; Pixel.new(p, q, v)
when 4; Pixel.new(t, p, v)
else; Pixel.new(v, p, q)
end
end
end
end
include Magick
img = ImageList.new("kabochamiku-src.png")
for y in 0...img.rows
for x in 0...img.columns
h, s, v = img.pixel_color(x, y).get_hsv
if h > 120 && h < 240 && v >= 0.3
h -= 180
h += 360 if h < 0
img.pixel_color(x, y, Pixel.from_hsv(h, s, v))
end
end
end
img.write("kabochamiku-out.png")
ミソなのは、髪の色かどうかの判断を、色をHSVに変換して表現していることである。HSVのメリットは、色を三原色の強さでなく「色の種類」「鮮やかさ」「明るさ」といった要素で表現しているので、例えば光の強さの変化などに影響されにくい形で条件式を書けることである。
RMagickには、HSVに似たHLSという形式での色表現が事前に組み込まれているのだが、これの挙動がどうもおかしいため、上記コードでは改めてHSVでの色の値を取得するメソッドを定義している。
変換元の画像"kabochamiku-src.png"として、以下の画像を使うとする。
このプログラムを実行した結果出力される画像"kabochamiku-out.png"は以下のようになった。かぼちゃっぽくなった。
※2009.3.14追記
ふと思い立って、gist.githubに貼り付けておきました。

