画像をExcelモザイク画像に変換する
画像からExcelのモザイク画像に変換するアホなPythonプログラムを作りますた。
元画像(jpg)はモザイク画像としてExcelファイルのシートに保存されます。
方法と手順の説明
◆ 画像をmatplotlibで読み込むとNumpy配列に変換されます。jpg画像は三次元配列になっており、三次元目方向にRGB色情報が、赤なら[255,0,0]
のように入っている。
◆ そのリストを16進数のカラーコードに変換する。先ほどの赤なら#ff0000
。
色の変換は次のように行う。
# 10進数→16進数の二桁表示に変換 print("{:02x}".format(255)) print("{:02x}".format(0))
ff
00
10進数の255は16進数でff、10進数の00は16進数で00に文字列として変換される。
◆ 全てのRGB色リストを16進数カラーコードに変換すると二次元になる。これをPandasでデータフレームにする。値がカラーコードの文字列が入った二次元のデータフレームができる。
◆ できたデータフレームの背景色を、値=カラーコードにスタイル変換する。背景色のついたデータフレームのテーブルが出来上がる。
◆ あとはpandas.to_excel(保存ファイル名)
でExcelファイルに保存して完成。
画像の読み込みと配列への変換
◆ 元の画像
これがExcelシートでモザイク画像にする。
import numpy as np import matplotlib.pyplot as plt # 元の画像ファイル fname = "hannya.jpeg" # 画像をmatplotlibでNumpy配列に変換 img = plt.imread(fname)
配列のRGBを16進数に変換
# 画像のRGB配列を16進数カラーコードに変換する関数 def make_color(img): x = img.shape[0] y = img.shape[1] rgb_list = [img[i][j] for i in range(x) for j in range(y)] color_code_list = [] for rgb in rgb_list: color_code = [] for v in rgb: color_code.append("{:02x}".format(v)) color_code = ["#" + "".join(color_code)] color_code_list.append(color_code) return color_code_list
この辺はもう少しスッキリ書けそうです。だがこのまま行く。
データフレームに変換
# 画像をカラーコードの配列に変換 code_list = make_color(img) # 画像と同じサイズの二次元配列にする color_style = np.array(code_list).reshape(img.shape[:2]) # データフレームにする color_style = pd.DataFrame(color_style) # データフレームの表示 color_style
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | #2a323f | #2a323f | #2a323f | #29313e | #29313e | #29313e | #28303d | #28303d | #29313e | #29313e | ... | #191c25 | #191c25 | #191c25 | #1a1d26 | #1a1d26 | #1a1d26 | #191c25 | #191c25 | #181b24 | #181b24 |
1 | #2a323f | #2a323f | #2a323f | #29313e | #29313e | #29313e | #28303d | #28303d | #29313e | #29313e | ... | #191c25 | #191c25 | #191c25 | #1a1d26 | #1a1d26 | #191c25 | #191c25 | #191c25 | #181b24 | #181b24 |
2 | #2a323f | #2a323f | #2a323f | #29313e | #29313e | #29313e | #28303d | #28303d | #29313e | #29313e | ... | #191c25 | #191c25 | #191c25 | #191c25 | #191c25 | #191c25 | #191c25 | #181b24 | #181b24 | #181b24 |
3 | #2a323f | #2a323f | #2a323f | #29313e | #29313e | #29313e | #28303d | #28303d | #29313e | #29313e | ... | #191c25 | #191c25 | #191c25 | #191c25 | #191c25 | #191c25 | #181b24 | #181b24 | #171a23 | #171a23 |
4 | #2a323f | #2a323f | #2a323f | #29313e | #29313e | #29313e | #28303d | #28303d | #29313e | #29313e | ... | #191c25 | #191c25 | #191c25 | #191c25 | #181b24 | #181b24 | #181b24 | #171a23 | #171a23 | #171a23 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
271 | #0a0c18 | #0a0c18 | #0b0d19 | #0b0d19 | #0c0e1a | #0c0e1a | #0c0e1a | #0c0e1a | #0d0f1b | #0d0f1b | ... | #0f0c15 | #0f0c15 | #0f0c15 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 |
272 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0d0f1b | #0d0f1b | ... | #110e19 | #110e19 | #110e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 |
273 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0d0f1b | #0d0f1b | ... | #110e19 | #110e19 | #110e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 |
274 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0d0f1b | #0d0f1b | ... | #110e19 | #110e19 | #110e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 |
275 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0b0d19 | #0d0f1b | #0d0f1b | ... | #110e19 | #110e19 | #110e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 | #100e19 |
276 rows × 183 columns
画像と同じサイズの二次元配列ができた。
それぞれの値は画像のRGBを16進数カラーコードに変換したそのものが入っている。
背景色をつける
上記のテーブルの値が背景色のカラーコードになっている。それらの値をデータフレームの背景色として関数で置換する。
# Pandasをインポート import pandas as pd # 背景色をカラーコードに変換する関数 def func(val): color = val return "background-color:%s" % color # 背景色を変換実行 df = color_style.style.applymap(func)
Excelファイルに保存して完成
# データフレームテーブルをExcelファイルに保存 df.to_excel("img_excel_mosaic.xlsx")
◆ パソコンで開いたモザイク画Excelシートのキャプチャ
シートを拡大すると、
元の画像が276×183のサイズでしたが、Excelシートにすると相当デカくなる。セル幅の縦横のせいか、モザイク画像が横広い。
元画像はもう少し小さい物を使った方が良かったかな。
以上です。