Blender Pythonにて色指定するときに、どこからが赤で、どこからがオレンジで、どこまでが青で、どこまでが紫か、ちょっと私にはわからず、悩んでおりました。
各ソフトの色の変え方
Blender Pythonでの色の変え方
ご存じの通り、Blender Pythonで色を変えようとすると下記のようにR,G,BにFloatで1~0の数値をRGBに入れる方法でマテリアルなどの色を変えます。R,G,B,αの順です。
import bpy
# 指定例
bpy.data.materials["cube1"].node_tree.nodes["ColorRamp"].color_ramp.elements[0].color = (1, 0.5, 0.5, 1)
しかし特に境目(閾値?)がないので、Floatで1~0の数値をRGBに入れる形は、色の命名が面倒です。
Excel VBAでの色の変え方
悩んでいたところで先日、エクセルVBAで色を指定するときのことを思い出しました。エクセルではRGB値による指定も出来ますが、142色を選ぶことも出来るようになっています。
' A1セルの色をアリスブルーに変える
Range("A1").Interior.Color = rgbAliceBlue
Range("A1").Interior.Color = 16775408
Range("A1").Interior.Color = RGB(240, 248, 255)

ちなみに10進数⇔8bitの変換は以下。
$$RGB = R + {G}\times{256} + {B}\times{256^2}$$
AliceBlueの例だと…
$$16775408 = 240 + {248}\times{256} + {255}\times{256^2}$$
となります。
Tableで表すとこんな感じ
”赤”ですと、Rが最大の255(0始まりなので256ではない)となることから、256で割って0~1にスケーリングします。
id | 名前 | 10進数値 | 説明 | R(8bit) | G(8bit) | B(8bit) | R(0~1) | G(0~1) | B(0~1) | color name |
---|---|---|---|---|---|---|---|---|---|---|
1 | rgbAliceBlue | 16775408 | アリスブルー | 240 | 248 | 255 | 0.941176471 | 0.97254902 | 1 | AliceBlue |
2 | rgbAntiqueWhite | 14150650 | アンティークホワイト | 250 | 235 | 215 | 0.980392157 | 0.921568627 | 0.843137255 | AntiqueWhite |
3 | rgbAqua | 16776960 | 水色 | 0 | 255 | 255 | 0 | 1 | 1 | Aqua |
4 | rgbAquamarine | 13959039 | アクアマリン | 127 | 255 | 212 | 0.498039216 | 1 | 0.831372549 | Aquamarine |
5 | rgbAzure | 16777200 | 空色 | 240 | 255 | 255 | 0.941176471 | 1 | 1 | Azure |
これをPythonから読み込み、color nameで指定して戻り値でRGB値を0~1で受けることができる関数を作りました。
PandasでRead
Pandasを使用しますので、あらかじめinstallしておいてください。(PYTHONPATHの設定もお忘れなく)
import pandas as pd
def Get_RGB_0to1lis_ms(color_name):
url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
df = pd.read_csv(url,
encoding='utf-8' ,
sep=',' ,
index_col=None
)
RGB_0to1lis = df[df['color name']==color_name]
return [RGB_0to1lis['R(0~1)'].values[0],
RGB_0to1lis['G(0~1)'].values[0],
RGB_0to1lis['B(0~1)'].values[0]]
RGB_0to1lis = Get_RGB_0to1lis_ms('DarkBlue')
# RGB_0to1lis is [0 0 0.545098039] when color_name='DarkBlue'
そして、ちょっとユニークな仕様ですが、乱数発生の整数をid指定して、ランダムな色が出てくるような関数も面白いのでは、と思って作りました。
下記の例は1~143の乱数を発生させてCube1のColorRampのelement0の色を変えるものです。
import pandas as pd
import random
import bpy
def Get_RGB_0to1lis_ms_byId(id_number):
# id number is 1 to 143
url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
df = pd.read_csv(url,
encoding='utf-8' ,
sep=',' ,
index_col=None
)
RGB_0to1lis = df[df['id']==id_number]
colorname = RGB_0to1lis['color name'].values[0]
return [RGB_0to1lis['R(0~1)'].values[0],
RGB_0to1lis['G(0~1)'].values[0],
RGB_0to1lis['B(0~1)'].values[0]] , colorname
[RGB_0to1lis,colorname] = Get_RGB_0to1lis_ms_byId(random.randint(1,143))
bpy.data.materials["cube1"].node_tree.nodes["ColorRamp"].color_ramp.elements[0].color = (RGB_0to1lis[0],
RGB_0to1lis[1],
RGB_0to1lis[2],
1)

おまけ
ちょっと謎なんですが、同じ色でつづりが異なるものが7つあるのでその重複を削除する必要があるのでお気をつけて。

143色→128色となります。reset_indexメソッドを使いますが、0始まりになってしまい、指定の番号が一つずれるので注意。また、関数内もilocで取りに行くカタチになるので、value[0]の記述も必要なくなります。(最初からこの指定のほうがよかったカモ)
import pandas as pd
def Get_RGB_0to1lis_ms_byId_noDup(df,id_number):
# id number is 0 to 127
RGB_0to1lis = df.iloc[id_number,:]
colorname = RGB_0to1lis['color name']
return [RGB_0to1lis['R(0~1)'],
RGB_0to1lis['G(0~1)'],
RGB_0to1lis['B(0~1)']] , colorname
url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
df_org = pd.read_csv(url,
encoding='utf-8' ,
sep=',' ,
index_col=None
)
df = df_org[~df_org.duplicated(keep=False,subset='10進数値')]
df.reset_index(drop=True, inplace=True) # index reset (この処理が入ると0始まりになる)
[RGB_0to1lis,colorname] = Get_RGB_0to1lis_ms_byId_noDup(df,2)
# RGB_0to1lis is [0 1 1] when color_name='Aqua'
余談ですが、調べてみるとExcel 2003までは、ワークシート上で表示できる色は56色だけのようで、機能が限られているが故、色の定義も簡単にできた時代だったんですかね。
皮肉だよね。全てを与えられると、何も出来ず、緩やかに死ぬなんて。
五条先生が言ってた。floatでほぼ無限の色を手に入れたことで、どこからが赤かわからなくなった人の一つのアイディアでした。
コメント