LoginSignup
11
2

ElixirでPNGを画像をRGBA形式の行列に変換したい

Last updated at Posted at 2021-12-22

以前、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画像をダウンロード

weather_icon = "https://raw.githubusercontent.com/pimoroni/inky/fc17026df35447c1147e9bfa38988e89e75c80e6/examples/phat/resources/icon-sun.png"
%{body: png, status: 200} = Req.get!(weather_icon)

PNG画像をピクセルに変換

  • pixelsを用いてPNGをRGBA形式の行列に変換します。
  • pixelsにより処理された画像は、「RGBA」の4バイトで1ピクセルを構成しています。
{: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

:tada::tada::tada:

Elixirコミュニティに初めて接する方は下記がオススメです

Elixirコミュニティ の歩き方 -国内オンライン編-

https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian

image.png

11
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
2