やっつけな日常(4) スマホでGo!まだfmt.Printしか使えないけれど画像出力はできる

Joseph Halfmoon

昔「年にひとつくらいは新しい言語(コンピュータの)をおぼえろ」というのを読んだ記憶があり。でも年に一つは無理。だいたいこの10年くらいまったく新規なしです。これではいけない。Termuxの復活のお陰でスマホでLinuxできるようになったので、けっこう人気らしいGo言語をスマホの上で練習してみることにいたしました。

※「やっつけな日常」投稿順 indexはこちら

※練習で作ったGoソースコード全部は末尾に

トホホ4連発のお陰で、スマホ上のLinux(ユーザモードで危なくないやつ)、結構使えるようになりました。clangとPythonが使えるのでこれで良いかとも思ったのですが、これを機会に新規言語をいくつか勉強しようと。年寄りの冷や水か。まずは Go 言語をTermux上にインストールして使ってみることにいたしました。インストールは簡単

$ pkg install golang

作業ディレクトリは、$HOME配下に go なるディレクトリを掘ればデフォルトでそこになるみたいです。

さて、吉例 Hello World は Go 言語にも当然あります。まずはそれをやってみます。

Go by Example: Hello World

Hello Worldだけなら、とても簡単。素晴らしいのが、go run でインタプリタ実行もできるし、go build でコンパイルもできるところ。人気が出るのは当たり前か。

練習サンプルは結果が画像になるのが良い

練習するといって、黒字に文字や数字が並ぶのはイマイチ心がときめかないです。やっぱり画像出力の方が嬉しい。達成感が違います。しかし、Hello Worldで学んだのは、fmt.Printlnなる、「いつもの」標準出力への印字です。勿論、Go言語にも各種のGUIやグラフィクス関係のモジュールが多数用意されているみたいでした。しかしHello Worldの2発目にそいつらはキツイ。

ちょっと考えて、年寄りは思い出しましたぞ(最近のことは直ぐに忘れるのが年寄りの忘却力ですが、昔のことは覚えているのです。)Linuxだったら PBM フォーマット使えば良いじゃん、テキストファイルを出力でも画像になるし。

そうでした。しかし、どんなフォーマットだったっけ? 以下のページにて、碧色工房様が解説されていました。

PNM(PPM/PGM/PBM)ファイルフォーマット

チョロいね(本当か?)ということで、見よう見まねで Go言語2発目を書いてみました。こんな感じ(全文は末尾に。)

SourceCodeEdit

 

動作確認

インタプリタの実行であれば、上記ファイルに対して以下でOK

$ go run trainPBM00.go

コンパイルして実行、できた画像を .png 形式にコンバートするところまでなら以下で(トホホな件で使った ImageMagickが再び活躍。)

$ go build trainPBM00.go
$ ./trainPBM00 >test.pbm
$ convert test.pbm test.png

単体でコンパイル済のオブジェクトを動かしたら、こんな感じ。

PbmFile

PNGコンバート済のファイルを、表のAndroidアプリに表示してもらったところが以下のよう。単なる黒い四角だけれども画像かけてますな。

test

まあ、PBMのままでは白黒だけれども、兄弟フォーマットの、PGM、PPMなどみな以下同文で行けそうなので、カラー化もバッチりな筈。ホントか?

ということで、スマホ使って Go の練習は出来るぞ、と。何十個か書いているうちには、なんとかなる?でも忘却力もあるし。

やっつけな日常(3) Raspberry Pi上でUSB接続を調べる2つの方法 へ戻る

やっつけな日常(5) スマホでGo! ロジスティック写像のカオスなパターン へ進む

Go プログラミングの練習2歩目、小さい四角を描くプログラム

早速BUGFIX1版

package main
import "fmt"

type pbmImage struct {
  width int
  height int
  BUF []int
}


func newPbmImage(w int, h int) *pbmImage {
  p := pbmImage{width: w, height: h}
  buf := make([]int, w*h)
  p.BUF = buf
  return &p
}

func dotXY(img *pbmImage, x int, y int, v int) bool {
  if x > (img.width -1) {
    return false
  } else if y > (img.height - 1) {
    return false
  } else {
    img.BUF[y*img.width + x] = v
  }
  return true
}

func writePBM(img *pbmImage) bool {
  fmt.Println("P1")
  fmt.Println(img.width, " ", img.height)
  for y := 0; y < img.height; y++ {
    for x := 0; x < img.width; x++ {
      fmt.Print(img.BUF[y*img.width + x], " ")
    }
    fmt.Println()
  }
  return true
}

func drawBOX(img *pbmImage, x1 int, y1 int, x2 int, y2 int) bool {
  for x := x1; x <= x2; x++ {
    dotXY(img, x, y1, 1)
  }
  for x := x1; x <= x2; x++ {
    dotXY(img, x, y2, 1)
  }
  for y := y1; y <= y2; y++ {
    dotXY(img, x1, y, 1)
  }
  for y := y1; y <= y2; y++ {
    dotXY(img, x2, y, 1)
  }
  return true
}

func main() {
  //fmt.Println("PBM training 000.")
  img := newPbmImage(32, 32)
  drawBOX(img, 2, 5, 30, 27) 
  writePBM(img)
}