2016/02/24

Recent entries from same category

  1. Go 言語プログラミングエッセンスという本を書きました。
  2. errors.Join が入った。
  3. unsafe.StringData、unsafe.String、unsafe.SliceData が入った。
  4. Re: Go言語で画像ファイルか確認してみる
  5. net/url に JoinPath が入った。

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, 300300)

        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, 300300)
        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;
  bordersolid 3px #5a5;
  color#585;
  padding20px;
}

#dropzone.dropover {
  background-color#cfc;
  color#9c9;
}
upload

便利。

Posted at by