色は3つの数で表す
コンピュータグラフィックスでは、色を赤、緑、青の3つの数で表します。この3つの数を混ぜると、新しい色や、半透明の重なりが作れます。
このレッスンでは、色の数の意味を知り、2つの色を混ぜ、透明度を使って重ねる計算をします。
このレッスンのゴール
メモ
赤、緑、青の数で色を表し、アルファ値で2つの色を混ぜられる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| RGB | 赤、緑、青の3つの数で色を表す方法 | (255, 0, 0) |
| チャンネル | 色を作る3つの数の1つ | |
| アルファ | 上に重ねた色が、どれだけ見えるかを表す数 | 50 |
| ブレンド | 2つの色を混ぜて、1つにすること | |
| 前景 | 上に重ねる色 | |
| 背景 | 下にある色 |
学生が入力するセルは、このプレビューでは空白です。
色は赤、緑、青の強さで決まる
画面の1つのピクセルは、赤、緑、青の光の強さで色を作ります。この3つの数の組を RGB と呼び、それぞれを 0 から 255 の整数で表します。
0 は光がない状態、255 は最も強い状態です。3つとも 0 なら黒、3つとも 255 なら白になります。
RGB の数と色の関係
| 色 | (赤, 緑, 青) | 光の様子 |
|---|---|---|
| 黒 | (0, 0, 0) | 光がない |
| 白 | (255, 255, 255) | 3色とも最大 |
| 赤 | (255, 0, 0) | 赤だけが最大 |
| 黄 | (255, 255, 0) | 赤と緑が最大 |
| 灰色 | (128, 128, 128) | 3色とも半分ほど |
学生が入力するセルは、このプレビューでは空白です。
光を足すと、255 で止まる
2つの色を光として足すときは、チャンネルごとに足し算をします。ただし、255 を超える値は作れないので、255 で止めます。
(180, 90, 0) と (120, 90, 30) を足すと、赤は 300 になりますが、255 で止まります。結果は (255, 180, 30) です。
チャンネルごとに足して、255 で止める
| チャンネル | 1つ目 | 2つ目 | 足した値 | 結果 |
|---|---|---|---|---|
| 赤 | 180 | 120 | 300 | 255 |
| 緑 | 90 | 90 | 180 | 180 |
| 青 | 0 | 30 | 30 | 30 |
学生が入力するセルは、このプレビューでは空白です。
光を足して 255 で止める
first = [180, 90, 0]
second = [120, 90, 30]
result = []
for channel in range(3):
total = first[channel] + second[channel]
if total > 255:
total = 255
result.append(total)
print(result)
# second の最初の値を 20 に変えて、もう一度実行します。
# 赤の結果は、いくつになりますか。
アルファは、重ねた色の濃さを決める
アルファは、前景がどれだけ見えるかを表す数です。ここでは 0 から 100 の割合で表します。0 なら背景だけ、100 なら前景だけが見えます。
混ぜた色は、チャンネルごとに、前景 × アルファ と 背景 × (100 − アルファ) を足し、100 で割って求めます。小数は切り捨てます。
赤を暗い青にアルファ 25 で重ねる
| チャンネル | 前景 | 背景 | 計算 | 結果 |
|---|---|---|---|---|
| 赤 | 200 | 0 | (200 × 25 + 0 × 75) ÷ 100 | 50 |
| 緑 | 0 | 0 | (0 × 25 + 0 × 75) ÷ 100 | 0 |
| 青 | 0 | 100 | (0 × 25 + 100 × 75) ÷ 100 | 75 |
学生が入力するセルは、このプレビューでは空白です。
青から赤へ変わる帯を作る
Pillow で、左は青、右は赤になる帯を作ります。x が増えるほど、赤の数が増え、青の数が減ります。
帯は ramp.png に保存します。表示するのは、左端、中央、右端のピクセルです。ramp.png を開くと、青から紫を通って、赤へ変わる帯が見えます。
青から赤への帯を ramp.png に保存
docker exec jupyter python3 -c "from PIL import Image; im = Image.new('RGB', (256, 32)); im.putdata([(x, 0, 255 - x) for y in range(32) for x in range(256)]); im.save('ramp.png'); print(im.getpixel((0, 0)), im.getpixel((128, 0)), im.getpixel((255, 0)))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
2つの色を混ぜると、いつも平均になると考えがちです。光を足すときは足し算で、255 で止まります。アルファで重ねるときだけ、アルファの割合で重みをつけた平均になります。
Pillow で半透明の四角を重ねる
Pillow の alpha_composite は、透明度つきの2枚を重ねます。青い 64 × 64 の背景の中に、赤い 32 × 32 の四角を、アルファ 128 で置きます。
Pillow のアルファは 0 から 255 の整数で、128 は約半分です。blend.png を開くと、青い四角の中に、赤みがかった紫の四角が見えます。表示は、背景だけの (0, 0) と、重なりの (20, 20) です。
赤い四角を青にアルファ 128 で重ねる
docker exec jupyter python3 -c "from PIL import Image; back = Image.new('RGBA', (64, 64), (0, 0, 255, 255)); front = Image.new('RGBA', (32, 32), (255, 0, 0, 128)); back.alpha_composite(front, (16, 16)); back.save('blend.png'); print(back.getpixel((0, 0)), back.getpixel((20, 20)))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。