🫐

Elixir で M5Stack CoreMP135 の液晶ディスプレイに図形を描く

2024/09/25に公開

本稿について

本稿では Elixir ライブラリ image を用いて M5Stack CoreMP135(以下、「CoreMP135」と呼ぶ)の液晶ディスプレイ(LCD)上に図形を描く方法について解説します。

拙稿 Elixir を M5Stack CoreMP135 上で動かす の内容に沿って Elixir を CoreMP135 にインストールしてあることが本稿の前提条件です。

Elixir スクリプト

次に示すのは、私が作成した Elixir スクリプト draw_circles.exs です。

Mix.install([
  {:image, "~> 0.54"}
])

import Bitwise

fb_width = 320
fb_height = 240

img = Image.new!(fb_width, fb_height)

img =
  img
  |> Image.Draw.circle!(160, 120, 50, color: "#0000ff")
  |> Image.Draw.circle!(200, 160, 20, color: "#ff0000")
  |> Image.Draw.circle!(120, 150, 30, color: "#00ff00")

{:ok, data} = Vix.Vips.Image.write_to_binary(img)

pixels =
  for <<r::8, g::8, b::8 <- data>> do
    r = r >>> 3
    g = g >>> 3
    b = b >>> 3
    <<b::5, r::6, g::5>>
  end

data = :erlang.list_to_bitstring(pixels)

File.open("/dev/fb1", [:binary, :write], fn file ->
  IO.binwrite(file, data)
end)

このスクリプトを CoreMP135 内の適当なディレクトリにおいて elixir draw_circles.exs コマンドで実行すると、LCD の表示が次のように変化します。

LCD

写真映りのせいで左下の円板が白く見えますが、実際には緑色です。

ソースコードの解説

5 行目をご覧ください。

import Bitwise

ビット操作演算子 >>> を使用するために Bitwise モジュールをインポートしています。

9 行目をご覧ください。

{:ok, img} = Image.new(fb_width, fb_height)

関数 Image.new!/3 を用いて、幅 320px、高さ 240px のキャンバスを作成しています。変数 img には、構造体 %Vix.Vips.Image{} がセットされます。

12-16 行をご覧ください。

img =
  img
  |> Image.Draw.circle!(160, 120, 50, color: "#0000ff")
  |> Image.Draw.circle!(200, 160, 20, color: "#ff0000")
  |> Image.Draw.circle!(120, 150, 30, color: "#00ff00")

関数 Image.Draw.circle!/5 を用いて、キャンバス上に 3 種類の円板を描いています。第 2 引数に中心の X 座標、第 3 引数に中心の Y 座標、第 4 引数に円の半径、第 5 引数は省略可能なオプションです。color オプションには #rrggbb 形式で色を指定しています。

18 行目をご覧ください。

{:ok, data} = Vix.Vips.Image.write_to_binary(img)

関数 Vix.Vips.Image.write_to_binary/1 を用いて、構造体 %Vix.Vips.Image{} をバイナリデータに変換しています。

このバイナリデータは、1 個のピクセルを 3 バイト(24 ビット)で表します。第 1 バイトが赤、第 2 バイトが緑、第 3 バイトが緑の値を表します。

20-26 行をご覧ください。

pixels =
  for <<r::8, g::8, b::8 <- data>> do
    r = r >>> 3
    g = g >>> 3
    b = b >>> 3
    <<b::5, r::6, g::5>>
  end

バイナリデータを CoreMP135 のフレームバッファに適合するピクセルデータのリストに変換しています。<<r::8, g::8, b::8 <- data>> は、data の先頭から 3 バイトずつを順に取り出して、1 バイトずつの 3 個の断片を変数 r, g, b にセットしています。

22 行目の r = r >>> 3 はビット操作演算子 >>> を利用して 3 ビット右にシフトしています。これにより 24 ビットで表現されるフルカラーのピクセルデータが、16 ビットのピクセルデータに変換されます。例えば、ビットストリング 1100111000011001 に変換されます。

<<b::5, r::6, g::5>> および 23 行目以降のコードに関しては、Elixir で M5Stack CoreMP135 の液晶ディスプレイに色を塗る を参照してください。

備考

  • 当初、本稿は「Elixir で CoreMP135 のフレームバッファを操作する②」というタイトルで公開されました。

参考文献

Discussion