2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rubyである色に近い色を導き出したい、という話

Last updated at Posted at 2021-02-03

初投稿です
自身の復習の目的として投稿致します。
あまりこういった発信は慣れていないことも有りますので、気になった点があれば**ここ違うよ!とかここ短くできるよ!**とかコメントを頂けると凄く喜びます

##これ is 何

  • 「ある色配列(RGB)に対して近い色を上手に探したいんだけどどうすればいいのか」を考えたときの産物となっております。
  • ポートフォリオに機能追加を行っていたときのものです。

##開発環境
ruby 2.6.3
Rails 5.2.4.4

##前提条件


sample = [255, 192, 103]
# お好みの色(RGB)を配列指定。
colors = { "red" => [220, 53, 69], "orange" => [255, 153, 51], "yellow" => [255, 193, 7], "green" => [40, 167, 69], "blue" => [0, 123, 255], "indigo" => [51, 51, 204], "purple" => [153, 51, 255]}
# Hashで指定。こちらもお好みで。

2色間の色差の計算は以下で行っています。


distance = \sqrt{{(R_2-R_1)}^2 + {(G_2-G_1)}^2+ {(B_2-B_1)}^2}

参考:色差(Wikipedia)

##実装

1.distanceを作る

distance = {}
# 空Hashを作る
colors.each{|key, value|
  r = "#{(value[0] - sample[0])**2}"
  g = "#{(value[1] - sample[1])**2}"
  b = "#{(value[2] - sample[2])**2}"
  distance[key] = "#{((r + g + b).to_i**(1 / 2.0)).round}"
  # p distance => 下部コンソール(1)にて
}
# keyには色、valueには色の配列が入るので、それぞれの配列の1~3番目の差を計算し2乗
# 合計した上でその平方根を計算、小数点以下を四捨五入している(前提条件より)。
コンソール(1)
{"red"=>"1106884"}
{"red"=>"1106884", "orange"=>"3900"}
{"red"=>"1106884", "orange"=>"3900", "yellow"=>"139"}
{"red"=>"1106884", "orange"=>"3900", "yellow"=>"139", "green"=>"679894"}
{"red"=>"1106884", "orange"=>"3900", "yellow"=>"139", "green"=>"679894", "blue"=>"8063838"}
{"red"=>"1106884", "orange"=>"3900", "yellow"=>"139", "green"=>"679894", "blue"=>"8063838", "indigo"=>"20400049"}
{"red"=>"1106884", "orange"=>"3900", "yellow"=>"139", "green"=>"679894", "blue"=>"8063838", "indigo"=>"20400049", "purple"=>"10200097"}

7色の色毎にdistanceを持った、Hashを生成することが出来ました。
しかし、このままでは見た目で分かっても、指定の色を引き出せないので…

2.distanceを並び替える

distance = {}
colors.each{|key, value|
  r = "#{(value[0] - sample[0])**2}"
  g = "#{(value[1] - sample[1])**2}"
  b = "#{(value[2] - sample[2])**2}"
  distance[key] = "#{((r + g + b).to_i**(1 / 2.0)).round}"
  # ここまでは1.と同様
      if key == "purple"
        sorted_dis = distance.sort {|(k1, v1), (k2, v2)| v1.to_i <=> v2.to_i }.to_h
        # valueの値によって、昇順に並び替える
        topcolor = sorted_dis.first.first
        # p topcolor => 下部コンソール(2)にて
      end
}
コンソール(2)
"yellow"

sampleに対しては、yellowが最も近いことが分かりました。
調べていくと、色に関しては色々な計算方法があり、まだまだ研究していかないといけない感じです!

ところで、

hoge.each{|key, value|}

を見て思い出しましたが、hashに対するeachはRailsのflashメッセージでも使っていたような…と思ったので、次回はエラーメッセージの分岐とか復習がてら書いていこうと思います。
ここまでご覧頂きまして、誠にありがとうございます。

参考にさせて頂いた記事

[Ruby] 便利な組み込みクラスのメソッド達(Hash編)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?