golang で Web アプリを作ってると画像のアップロード処理を書くことって意外と多くて、その度にググったり過去の自分の実装を調べたりして、みたいな事を繰り返してましたが go-imageupload を使うとかなり端折れる事になりそうです。
GitHub - olahol/go-imageupload: Gracefully handle image uploading and thumbnail creation.
https://github.com/olahol/go-imageupload
実装は簡素ですが、毎回自分でこれを書いてたと思うと時間が勿体ないですね。使い方も簡単で README.md から転用すると 300x300 のサムネイル画像を生成するのはこれだけになります。
package main
import (
"github.com/gin-gonic/gin"
"github.com/olahol/go-imageupload"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.File("index.html")
})
r.POST("/upload", func(c *gin.Context) {
img, err := imageupload.Process(c.Request, "file")
if err != nil {
panic(err)
}
thumb, err := imageupload.ThumbnailPNG(img, 300, 300)
if err != nil {
panic(err)
}
thumb.Write(c.Writer)
})
r.Run(":5000")
}
サムネイルとは書いてますが、サイズが指定出来るので例えばアップロード画像のサイズを均一にしたい場合にも使えます。ブラウザ側の処理も dropzone.js を使えば簡単にアップロード画面が出来上がります。
まずはサーバ側のコード。
package main
import (
"crypto/sha1"
"fmt"
"time"
"github.com/gin-gonic/contrib/static"
"github.com/gin-gonic/gin"
"github.com/mattn/go-colorable"
"github.com/olahol/go-imageupload"
)
func main() {
gin.DefaultWriter = colorable.NewColorableStdout()
r := gin.Default()
r.Use(static.Serve("/", static.LocalFile("./assets", true)))
r.POST("/upload", func(c *gin.Context) {
img, err := imageupload.Process(c.Request, "file")
if err != nil {
panic(err)
}
thumb, err := imageupload.ThumbnailPNG(img, 300, 300)
if err != nil {
panic(err)
}
h := sha1.Sum(thumb.Data)
thumb.Save(fmt.Sprintf("files/%s_%x.png",
time.Now().Format("20060102150405"), h[:4]))
})
r.Run(":5000")
}
アップロードされた画像を 300x300 にリサイズして、日付と sha1 のファイル名付けて保存しているだけです。files
というディレクトリに保存されます。クライアント側も dropzone.js 様様です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>あぷろだ</title>
<link rel="stylesheet" href="dropzone.css" media="all">
<link rel="stylesheet" href="app.css" media="all">
<script src="dropzone.js"></script>
</head>
<body>
<form action="/upload" class="dropzone" id="dropzone"></form>
</body>
</html>
一応、マウスホバーで色変えちゃうよ的な。
#dropzone {
background-color: #afa;
border: solid 3px #5a5;
color: #585;
padding: 20px;
}
#dropzone.dropover {
background-color: #cfc;
color: #9c9;
}
便利。