以前、Inky pHATというEペーパーディスプレイにPNG画像を表示させたいときのことです。
ElixirでPNG画像をピクセルに変換する方法が中々見つからず、手こずってました。
Eペーパーディスプレイ上ではピクセルごとに色を指定する必要があるのです。
後学のためにElixirでPNGをピクセルに変換する方法をメモを残します。
「JupyterNotebook + NumPyでサクッと画像加工するノリ」をElixirでやってみた(lennaさんのバージョンアップもあるよ) by @piacerex が参考になりました。
「nerves_inky_phat_weather_example」サンプルNervesファームウエア(拙作)
やりたいこと
- プログラミング言語:Elixir
- PNGアイコン画像をRGBA形式の行列に変換して自由に加工したい。
本アイコン画像はEペーパーディスプレイのメーカーのリポジトリーから直接ダウンロードできます。
IExでデモ
IExを起動
iex
依存関係をインストール
- 環境変数
CROSSCOMPILE
に何らかの値をセットしておかないとpixelsがうまくコンパイルされませんでした。(MacOS)
Mix.install([{:pixels, "~> 0.2.1"}, {:req, "~> 0.2.1"}, {:nx, "~> 0.1.0"}], system_env: [{"CROSSCOMPILE", "1"}])
PNG画像をダウンロード
- ここでは例としてPimoroniのお天気アイコンを使用。
- LivebookコアチームオススメのHTTPクライアントreqを用いてPNG画像をダウンロードします。
weather_icon = "https://raw.githubusercontent.com/pimoroni/inky/fc17026df35447c1147e9bfa38988e89e75c80e6/examples/phat/resources/icon-sun.png"
%{body: png, status: 200} = Req.get!(weather_icon)
PNG画像をピクセルに変換
{:ok, %{data: data, height: height, width: width}} = Pixels.read(png)
後は好きなようにデータを加工する
data
|> :binary.bin_to_list
|> Enum.chunk_every(4)
|> Enum.map(fn
[_, _, _, 0] -> 0
_ -> 1
end)
|> Enum.chunk_every(width)
|> Nx.tensor
|> Nx.to_heatmap
Elixirコミュニティに初めて接する方は下記がオススメです
Elixirコミュニティ の歩き方 -国内オンライン編-
https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian