写真の色を反転しよう
今回は写真の色を反転して、ネガフィルムのような感じにしてみましょう。
色を反転させるということは、黒(0,0,0)を白(255,255,255)にするということです。
赤の場合はRGBが(255,0,0)なので、(0,255,255)となり水色になります。
ピクセルを編集する
色を反転させるために各ピクセルを編集します。
ピクセルを編集するために、pygame.PixelArray()を使います。
戻り値としてピクセルが編集可能な画面オブジェクトが返されます。
このオブジェクトは、画面のピクセルを縦横の二次元配列で操作できます。
pygame.PixelArray(画面オブジェクト)
以下の例は、imgという画面オブジェクトをpixelという編集できるピクセル情報にして、X座標0、Y座標0のピクセルを青(0,0,255)にしています。
実行例
pixel = pygame.PixelArray(img)
pixel[0][0] = (0,0,255)
色情報をRGBA形式に変換する
ピクセルに入っている色情報は、カラー定数という0(黒)から16777215(白)までの整数値になっているため、それをRGBA(赤、緑、青、透明度)形式に変換する必要があります。
戻り値に赤、緑、青、透明度のリストが返ってきます。
画面オブジェクト.unmap_rgb(カラー定数)
実行例
rgba = surface.unmap_rgb(pixel[0][0])
rgbaの中は、(61, 70, 137, 255) のような形で入っています。
色を反転する
色を反転するには、RGBの各要素を排他的論理和(XOR)でビット反転させます。
例えば10進数の80は、2進数では01010000となりますが、これを反転させるには2進数の11111111で排他的論理和を計算します。
結果は2進数で10101111、10進数では175となります。
Pythonでは排他的論理和は、^(ハット)記号を使います。
一般的には、2進数だと桁が多くなって分かりづらいので、16進数を使います。(10進数を使っても結果は同じです)
>>> 80 ^ 0xff
175
>>> 80 ^ 255
175
>>> 80 ^ 0b11111111
175
メモ
実は 255 - 80 = 175 となるように、 排他的論理和の結果は、255から色の値を引くことと同じです。
編集したピクセル情報を削除する
pygame.PixelArray()は、画面をロックしてしまうので、pygame.PixelArray()で作ったオブジェクトを削除する必要があります。
削除にはdel文を使います。
del ピクセル編集用画面オブジェクト
実行例
del pixel
写真の色を反転させるプログラム
上記のことをふまえて、第12回で作ったプログラムを改造して、写真の色を反転させてみましょう。
なお、正しく色を反転させるために、写真を読み込むときに convert()を使って、ピクセル情報をディスプレイに合わせる必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
### インポート import pygame from pygame.locals import * ### 定数 WIDTH = 640 # 幅 HEIGHT = 400 # 高さ BIT_COLOR = 0xff # ビット演算用 ### モジュール初期化 pygame.init() ### 画面設定 surface = pygame.display.set_mode((WIDTH,HEIGHT)) ### 写真読み込み img = pygame.transform.rotozoom(pygame.image.load("photo.jpg").convert(), 0, 0.2) ### 写真のピクセル情報を直接編集 pixel = pygame.PixelArray(img) ### Y座標、X座標の色を取得 for y in range(img.get_height()): for x in range(img.get_width()): ### カラー定数をRGBA形式に変換 rgba = surface.unmap_rgb(pixel[x][y]) ### 各色を排他的論理和で変換 rgba_r = rgba[0] ^ BIT_COLOR rgba_g = rgba[1] ^ BIT_COLOR rgba_b = rgba[2] ^ BIT_COLOR ### 色を書き換え pixel[x][y] = (rgba_r,rgba_g,rgba_b) ### オブジェクト削除 del pixel ### 写真表示 surface.blit(img, (int((WIDTH-img.get_width())/2),int((HEIGHT-img.get_height())/2))) ### 画面更新 pygame.display.update() ### 無限ループ while True: ### イベント処理 for event in pygame.event.get(): if event.type == KEYDOWN and event.key == K_ESCAPE: break else: continue ### whileループ終了 break ### 終了処理 pygame.quit() |
プログラムを実行すると、以下の画像が表示されます。