golangでmultipart.File型の画像をリサイズ〜S3にアップロードするまで


概要

golang製のAPIサーバーを個人開発する中で、フロント側から受け取った画像ファイルをリサイズ等編集して、S3にアップロードするロジックを実装しました。その際、結構苦戦したので、要点をまとめていきたいと思います。

実践

multipart/form-dataをパース

file, _, err := r.FormFile("image")

fileにmultipart.File型としてgoで扱えるようになります。

バッファーに内容を流し込む

img := &models.Image{
        UserID: uid,
        Buf:    &bytes.Buffer{},
    }

    _, err := img.Buf.ReadFrom(file)
    if err != nil {
        return &models.Image{}, err
    }

今回のアプリはレイヤードアーキテクチャ+DDDを採用しているので、Imageモデルをポインタ型で宣言して、参照渡しでバッファーにデータを流し込んでます。この時バッファーを格納するBufも宣言してあげないと、アドレス領域が確保されずnilエラーが発生してしまうので、注意が必要です。

画像編集

func ResizeImage(i *models.Image) error {
img, t, err := image.Decode(i.Buf)
    if err != nil {
        return err
    }

省略

err = jpeg.Encode(i.Buf, m, nil)
        if err != nil {
            return err
        }

バッファー型にすればデコード・エンコード可能になるので、ここでリサイズ等画像編集する。

S3にアップロード

uploader := s3manager.NewUploader(sess)
        _, err = uploader.Upload(&s3manager.UploadInput{
            Bucket: aws.String("example"),
            Key:    aws.String(img.Name),
            Body:   img.Buf,
        })

バッファー型のままアップロード可能なので、対象のバケット、名前等定義すれば完了!!

参考資料

Goでmultipart/form-dataをparseする
AWS SDK for Go S3バケット基本操作
リアルタイム画像リサイズAPIをGo + Serverless Application Modelで作った時の感想