My External Storage

Apr 22, 2020 - 3 minute read - Comments - go

The Go Playgroundの実行結果に画像を出力する

Go Playgroundのテンプレートを見ていたら画像を出力できることを発見した。

実行結果

TL;DR

  • The Go Playgroundにテンプレートが追加された
  • テンプレートの中にfaviconを描画するコードがある
  • Playground上でIMAGE:を先頭に付与してbase64エンコーディングして出力すると画像が表示できる
var buf bytes.Buffer
png.Encode(&buf, img)
fmt.Println("IMAGE:" + base64.StdEncoding.EncodeToString(buf.Bytes()))

The Go Playgroundにテンプレートが追加された

The Go Playgroundはブラウザ上でGoのコードを実行できるオンラインエディタだ。 近年、複数ファイルを含んだサンプルコードを実行できるようになったり、標準パッケージ以外もimportできるようになっている。 そして先日からテンプレートが選択できるようになった。

テンプレートの内容自体はgithub.com/golang/playground/examplesで確認することができる。

このテンプレートの中のひとつにPlayground上で画像を出力するサンプルコードがある。

The Go Playgroundで出力結果に画像を表示する。

画像を描画するサンプルコードは次のとおり(コードは抜粋したコード)。

import (
  "bytes"
  "encoding/base64"
  "fmt"
  "image/png"
)

var buf bytes.Buffer
png.Encode(&buf, img)
fmt.Println("IMAGE:" + base64.StdEncoding.EncodeToString(buf.Bytes()))

サンプルコード通りにイメージを標準出力すれば任意のフルカラーの画像をThe Go Playgroundで表示することができる。

ここでは練習問題で多用される(?)マンデルブロ集合を描画してみる。

書籍「プログラミング言語Go」のサンプルコードを使ってThe Go Playground上でマンデルブロ集合の画像を出力するコードは次の通り。

package main

import (
  "bytes"
  "encoding/base64"
  "fmt"
  "image"
  "image/color"
  "image/png"
  "math/cmplx"
)

func main() {
  displayImage()
}

func displayImage() {
  const (
    xmin, ymin, xmax, ymax = -2, -2, +2, +2
    width, height          = 128, 128
  )

  img := image.NewRGBA(image.Rect(0, 0, width, height))
  for py := 0; py < height; py++ {
    y := float64(py)/height*(ymax-ymin) + ymin
    for px := 0; px < width; px++ {
      x := float64(px)/width*(xmax-xmin) + xmin
      z := complex(x, y)
      // Image point (px, py) represents complex value z.
      img.Set(px, py, mandelbrot(z))
    }
  }
  var buf bytes.Buffer
  err := png.Encode(&buf, img)
  if err != nil {
    panic(err)
  }
  fmt.Println("IMAGE:" + base64.StdEncoding.EncodeToString(buf.Bytes()))
}

func mandelbrot(z complex128) color.Color {
  const iterations = 200
  const contrast = 15

  var v complex128
  for n := uint8(0); n < iterations; n++ {
    v = v*v + z
    if cmplx.Abs(v) > 2 {
      r := 255 - contrast*n
      g := contrast * n
      b := g
      return color.RGBA{r, g, b, 255}
    }
  }
  return color.Black
}

上記のコードをThe Go Playground上で実行すると以下のようになる。

実行結果

実行結果としてマンデルブロ集合画像が描画されているのがわかる。

終わりに

The Go Playgroundに追加されたテンプレートを眺めていたらこの機能を見つけた。
追加されたテンプレートの中には複数ファイルの書き方や、CLI上の進捗バー描画などもある。
実務で使うことはほぼないであろうコードばかりだが、勉強になるので一度全部見ておくと良さそうだ。

参考

関連記事