はじめに
どうも僕です。
X(旧Twitter)をみているとこんな記事がありました。
どうやら9/6は 「松崎しげるの日」 らしいです。
そして、サクラクレパス公式からの色の配色。
・・・CSSで書いてみるか!
そう思ってしまったので、なんかやってみます。
どうやって実装するか
先ほどのツイートから、なんとなく
色用意して混ぜたらいけるっしょ!
と思いました。
方法1:color-mix
を使って色を混ぜる
どうやら2色であれば色を混ぜれるらしい。
2色しか混ぜれないらしいので、ネストしまくる。
See the Pen Untitled by Marnyさん (@Marny-the-vuer) on CodePen.
・・・なんか色変じゃね?
失敗だ
方法2:mix-blend-mode
で色をかさねる
mix-blend-mode
は色をいくつか重ねることで色を変えれるらしい。
See the Pen Untitled by Marnyさん (@Marny-the-vuer) on CodePen.
お!なんか近くね??
でもなんかもっと黒い気がする。
こいつめっちゃ惜しいな。
カラーコードどんなんだろ?と思い、調べてみると#e5a26b
となった
実際の色
実際の松崎しげる色のカラーコードってどうなんだろう。
調べてみると一瞬で出てきた
#A55A4A
らしい。
See the Pen Untitled by Marnyさん (@Marny-the-vuer) on CodePen.
いやめっちゃ濃いな。
なんか色を重ねるだけじゃ無理そうだな
方法3:カラーコードを計算してみる
カラーコードって計算で出せるっしょ!ってことでやってみる
def hex_to_rgb(hex_color):
# 16進数カラーコードをRGBに変換
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
def rgb_to_hex(rgb_color):
# RGBを16進数カラーコードに変換
return '#{:02x}{:02x}{:02x}'.format(rgb_color[0], rgb_color[1], rgb_color[2])
def mix_colors(colors, ratios):
# 各色と比率に基づいて色を混ぜる
mixed_color = [0, 0, 0]
total_ratio = sum(ratios)
for i, color in enumerate(colors):
rgb = hex_to_rgb(color)
ratio = ratios[i]
mixed_color[0] += rgb[0] * ratio
mixed_color[1] += rgb[1] * ratio
mixed_color[2] += rgb[2] * ratio
# 平均して最終的な色を計算
mixed_color = [int(c / total_ratio) for c in mixed_color]
return rgb_to_hex(tuple(mixed_color))
# 使用例:黄色、朱色、緑、白を指定した比率で混ぜる
colors = ['#FFFF00', '#eb6101', '#3eb370', '#FFFFFF'] # 黄色、朱色、緑、白
ratios = [0.25, 0.45, 0.14, 0.16] # 割合
mixed_color = mix_colors(colors, ratios)
print(f"混ぜた結果の色: {mixed_color}")
こんな感じらしいっすよ。ありがとうChatGPT。
うぉら!実行!
混ぜた結果の色: #daad38
ふむふむ。全然違くね?
逆算してみる
import numpy as np
from scipy.optimize import minimize
def hex_to_rgb(hex_color):
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
def rgb_to_hex(rgb_color):
return '#{:02x}{:02x}{:02x}'.format(rgb_color[0], rgb_color[1], rgb_color[2])
def color_distance(weights, *colors):
# 各基準色に対して重み付きの和を取り、目標色との距離を最小化
target_color = colors[-1]
mixed_color = np.zeros(3)
for i, weight in enumerate(weights):
mixed_color += np.array(colors[i]) * weight
# 目標色との誤差(距離)を返す
return np.linalg.norm(mixed_color - np.array(target_color))
def optimize_color_mixing(base_colors, target_color):
# 基準色をRGBに変換
base_colors_rgb = [hex_to_rgb(color) for color in base_colors]
target_rgb = hex_to_rgb(target_color)
# 比率の初期値を等分に設定し、制約条件は比率の合計が1
initial_weights = [1.0 / len(base_colors)] * len(base_colors)
bounds = [(0, 1)] * len(base_colors) # 各比率は0から1の間
constraints = {'type': 'eq', 'fun': lambda w: sum(w) - 1}
# 最適化を実行
result = minimize(color_distance, initial_weights, args=(*base_colors_rgb, target_rgb),
bounds=bounds, constraints=constraints)
if result.success:
return result.x # 最適な比率
else:
raise ValueError("最適化に失敗しました")
# 使用例:黄色、朱色、緑、白の基準色を使って、目標色#A55A4Aに近づける
base_colors = ['#FFFF00', '#FF4500', '#008000', '#FFFFFF'] # 黄色、朱色、緑、白
target_color = '#A55A4A' # 目標とする色
optimal_ratios = optimize_color_mixing(base_colors, target_color)
print("最適な比率:", optimal_ratios)
ありがとう。ChatGPT(2回目)
ということで実行。
最適な比率: [0. 0.48470684 0.3221515 0.19314166]
らしい。
この値を使って、最初のコードに代入してみる
混ぜた結果の色: #b79955
なるほどね(諦め)
結論
色を作るのは難しい。