プログラム日記φ(..)

おもにPython関係のプログラムメモ

PythonでGIF画像のカラーパレットを取り出してみる

先日、ETOPO1のグローバル地形データセットで地球の全体地図を描いてみましたが

 

memomemokun.hateblo.jp

 

地形の色分けを 、もっと、それらしく、NOAAのETOPO1の画像のような感じにしてみたいなと思い、

ETOPO1 Global Relief | NCEI

f:id:memomemokun:20190202063301j:plain


上の画像を、元の画像とほとんど遜色のない256色のGIF画像に減色た際に使われているGIF画像のパレットの色はどんな色なのか、GIF画像に割り当てられているカラーパレットの各色を取り出し、使われている色がわかりやすいように各色を表にしてみました。

 

こんな感じ

 

GIF画像に割り当てられているカラーパレットの各色を取り出してみる

GIF画像に割り当てられているカラーパレットの各色を取り出してみる

 

ソースは以下

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

def rgb2hex(r,g,b): #RGBを16進数表現へ
    # r , g , b = 0 〜 255
    hex_color = '#%02X%02X%02X' % (r, g , b)
    return hex_color


pil_img = Image.open('etopo1_ice_low.gif')

# カラーパレットを取り出す
palette = pil_img.getpalette()

# リストの値は index=0 から順番に [R, G, B, R, G, B, ...]のフラットな配列なので[R, G, B]単位にreshape
palette = np.array(palette).reshape(-1, 3)

# カラーパレットを16進数表現に変換
colors =  sorted([rgb2hex(col[0],col[1],col[2]) for col in palette])


n = len(colors)
ncols = 4
nrows = n // ncols + 1

fig, ax = plt.subplots(figsize=(8, 8))

# figsizeに応じて各色を描画する行と列のサイズを調整
X, Y = fig.get_dpi() * fig.get_size_inches()
h = Y / (nrows + 1)
w = X / ncols


# カラーパレットを各色毎に描画
for i, color in enumerate(colors):
    
    col = i % ncols
    row = i // ncols
    y = Y - (row * h) - h

    xi_line = w * (col + 0.05)
    xf_line = w * (col + 0.25)
    xi_text = w * (col + 0.3)

    ax.text(xi_text, y, color, fontsize=(h * 0.8),
            horizontalalignment='left',
            verticalalignment='center')

    ax.hlines(y + h * 0.1, xi_line, xf_line,
              colors=color, linewidth=(h * 0.6))


ax.set_xlim(0, X)
ax.set_ylim(0, Y)
ax.set_axis_off()

# 描画
fig.subplots_adjust(left=0, right=1,
                    top=1, bottom=0,
                    hspace=0, wspace=0)

plt.savefig('1.jpg', dpi=96)
plt.show()