🐈
Goのテンプレートエンジンを使用して、画像を一覧表示してみた。
はじめに
Go言語で画像アップロードする方法は分かっていても、それを画像一覧表示しようとして1週間以上詰まってしまったのでメモ。
検索しても特に記事が引っ掛からなかったので、残しておきたいと思います。
あなただれ
生まれて初めて記事を執筆しました。ご指摘ございましたらコメント下さると助かります。🙏
2021年1月から(約5ヶ月目)からプログラミングの勉強し開始しましたkinariと申します。
今は、自分の周りで未経験からGo言語を選択した人がいなくてえっちらおっちらしております。
執筆した背景
標準パッケージのみで画像を表示したいけど、どうすればいいか分からない。
→ 単体の画像は表示できることがわかった。
→ でも複数枚表示するにはどうしたらいいんだろう?(←今ここ)
環境
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.7
BuildVersion: 19H1217
$ go version
go version go1.16.2 darwin/amd64
ディレクトリ構成
$ tree
.
├── assets // ここに表示したい画像をおきます。
│ ├── levi.jpg
│ └── tanjiro.jpeg
├── main.go
└── templates
└── index.html
やりたいこと
1ページに画像一覧表示をしてみたい!
やったこと
main.go
package main
import (
"bytes"
"encoding/base64"
"github.com/nfnt/resize"
"image"
"image/jpeg"
"log"
"net/http"
"os"
"text/template"
)
func IndexHandler(w http.ResponseWriter, r *http.Request) {
dir, err := os.Open("assets/")
defer dir.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
allImageNames, err := dir.Readdirnames(-1) // それぞれの画像ファイルの名前を配列に格納します
if err != nil {
log.Fatalln("No files")
}
var decodeAllImages []image.Image
for _, imageName := range allImageNames { // 全ての画像をデコード、リサイズしてdecodeAllImageseに格納します
file, _ := os.Open("assets/" + imageName)
defer file.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
decodeImage, _, err := image.Decode(file)
resizedDecodeImage := resize.Resize(300, 0, decodeImage, resize.Lanczos3) // サイズを揃えるために横幅を300に固定します
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
decodeAllImages = append(decodeAllImages, resizedDecodeImage)
}
writeImageWithTemplate(w, decodeAllImages)
}
// writeImageWithTemplateで画像をエンコードします。
func writeImageWithTemplate(w http.ResponseWriter, decodeAllImages []image.Image) {
var encordImages []string
for _, decodeImage := range decodeAllImages {
buffer := new(bytes.Buffer)
if err := jpeg.Encode(buffer, decodeImage, nil); err != nil {
log.Fatalln("Unable to encode image.")
}
str := base64.StdEncoding.EncodeToString(buffer.Bytes())
encordImages = append(encordImages, str)
}
data := map[string]interface{}{"Images": encordImages}
renderTemplate(w, data)
}
// renderTemplateで渡された画像をテンプレートエンジンに渡します。
func renderTemplate(w http.ResponseWriter, data interface{}) {
var templates = template.Must(template.ParseFiles("templates/index.html"))
if err := templates.ExecuteTemplate(w, "index.html", data); err != nil {
log.Fatalln("Unable to execute template.")
}
}
func main() {
http.HandleFunc("/", IndexHandler)
http.ListenAndServe(":8080", nil)
}
index.html
でテンプレートエンジンを使用して、複数枚の画像を表示します。(画像一覧表示)
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>画像一覧表示</title>
</head>
<body>
<!-- Goのテンプレートエンジンの中でも、イテレータアクション(反復処理)を使用します。 -->
<!-- ここに「"Images": encordImages」の複数枚の画像が一覧表示されていきます。 -->
{{ range .Images }}
<img src="data:image/jpg;base64,{{ . }}" /><br />
{{ end }}
</body>
</html>
結果
無事、画像一覧表示がされました!
Github
Github にもコードをアップしました。
参考
Golangで画像をアップロードして表示するだけのアプリをつくってみた - 一から勉強させてください
Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る - インプレスブックス
Discussion