「闘魂」Elixir　〜文字を書いた画像からヒートマップを表示しよう〜


「elixir雑談-elixirと見習い錬金術師」のDiscodeで

![•-Discord-🌼｜elixir雑談-elixirと見習い錬金術師.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/596dcfba-d7ac-ba45-6652-aafc226cd8cd.png)

なるほど、『闘魂』は見慣れてきましたね
だったら、もっとコンソールに大きく『闘魂』を表示したいと思いました

![Screenshot from 2022-12-01 19-18-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/8e815deb-3163-2670-049f-72cb62722323.png)


# プロジェクトの作成

コマンドラインからプロジェクトを作成します
```sh
$ mix new hoge
```

実行結果
```sh
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/hoge.ex
* creating test
* creating test/test_helper.exs
* creating test/hoge_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd hoge
    mix test

Run "mix help" for more commands.
```

hoge プロジェクトに移動します

```sh
$ cd hoge
```

# 必要なライブラリを設定しよう
Elixirはmix.exsのdepsにライブラリーの設定ができます

今回使うライブラリー
・nx (本来はテンソルを操作するに便利なライブラリー、だが今回はコンソールに画像を表示するために使います)

https://hexdocs.pm/nx/Nx.html

・mogrify　ImageMagicを操作する（今回は『闘魂』の文字画像を使う）

https://hexdocs.pm/mogrify/Mogrify.html

・stb_image 画像のエンコードとデコードを扱う（今回はnxが扱える形式の変換に使う）

https://hexdocs.pm/stb_image/StbImage.html


mix.exsファイルを編集しましょう

```diff_elixir:mix.exs
defmodule Hoge.MixProject do
  use Mix.Project

  def project do
    [
      app: :hoge,
      version: "0.1.0",
      elixir: "~> 1.13",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
+     {:nx, "~> 0.4.0"},
+     {:mogrify, "~> 0.9.2"},
+     {:stb_image, "~> 0.5"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end
```

# 『闘魂』をコンソールに表示するプログラムの作成
・Mogrify.Imageで『闘魂』が書かれたhoge.pngを作成する
・hoge.pngを読み込む
・StbImageでnxが扱える形式に変換する
・ヒートマップを作成してコンソールに表示する

lib/hoge.exを編集しましょう

```diff_elixir:lib/hoge.ex
defmodule Hoge do
  import Mogrify

  @moduledoc """
  Documentation for `Hoge`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Hoge.hello()
      :world

  """
  def hello do
    :world
  end

+ def exec do
+   %Mogrify.Image{path: "hoge.png", ext: "png"}
+   |> custom("size", "40x20")
+   |> custom("background", "#000000")
+   |> custom("fill", "#FFFFFF")
+   |> custom("pango", "闘魂")
+   |> create(path: ".")

+   nx_image =
+     File.read!("hoge.png")
+     |> StbImage.read_binary!()
+     |> StbImage.to_nx()

+   nx_image[channels: 0]
+   |> Nx.to_heatmap()
+ end
end
```

# 実行する前の下準備
ライブラリーを取得しましょう
コマンドラインで

```sh
$ mix deps.get
```

実行結果
```sh
Resolving Hex dependencies...
Dependency resolution completed:
New:
  complex 0.4.2
  elixir_make 0.6.3
  mogrify 0.9.2
  nx 0.4.0
  stb_image 0.5.2
* Getting nx (Hex package)
* Getting mogrify (Hex package)
* Getting stb_image (Hex package)
* Getting elixir_make (Hex package)
* Getting complex (Hex package)
```

# プログラムを実行しましょう
コマンドラインで

```sh
$ iex -S mix
```


iex が立ち上がりコンパイルも行われます

```Elixir
Erlang/OTP 25 [erts-13.0.3] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

==> complex
Compiling 2 files (.ex)
Generated complex app
==> nx
Compiling 27 files (.ex)
Generated nx app
==> mogrify
Compiling 9 files (.ex)
Generated mogrify app
==> elixir_make
Compiling 1 file (.ex)
Generated elixir_make app
==> stb_image
cc -shared -std=c11 -O3 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fPIC -I/home/user/.asdf/installs/erlang/25.0.3/erts-13.0.3/include -I/home/user/hoge/deps/stb_image/3rd_party/stb /home/user/hoge/deps/stb_image/c_src/stb_image_nif.c -o /home/user/hoge/_build/dev/lib/stb_image/priv/stb_image_nif.so
Compiling 2 files (.ex)
Generated stb_image app
==> hoge
Compiling 1 file (.ex)
Generated hoge app
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
```

実行しましょう
```elixir
iex(1)> Hoge.exec()
```

このように実行されました
![Screenshot from 2022-12-01 19-18-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/8e815deb-3163-2670-049f-72cb62722323.png)