0
0

Go初心者でもNext.jsとGoでWebアプリを作りたい!その3

Posted at

写真の保存

今回はフロント側で撮った写真をバックエンドに送信し、保存する処理について取り扱います。

1. バックエンド側でupload処理を実装

usecase/upload_img.go

package usecase

import (
	"fmt"

	"github.com/gin-gonic/gin"
	"net/http"
	"path/filepath"
)

func UploadImg(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		c.String(http.StatusBadRequest, "get form err: %s", err.Error())
		return
	}

	savepath := filepath.Join("./images", file.Filename)

	if err := c.SaveUploadedFile(file, savepath); err != nil {
		c.String(http.StatusBadRequest, fmt.Sprintf("upload error: %s", err.Error()))
		return
	}
	c.String(http.StatusOK, fmt.Sprintf("success", file.Filename))
}

この処理の流れとしてはformで送られてきたデータから、file=画像データを取得し、imagesフォルダ内に画像を保存するようになっています。

この処理をmain関数内で呼び出します。

main.go
package main

import (
	"fmt"

	"github.com/gin-gonic/gin"
	"next_go_app/backend/usecase"
)

func main() {

	router := gin.Default()

	router.GET("/", func(c *gin.Context) {
		fmt.Println("Hello")
		c.JSON(200, gin.H{
			"message": "Hello",
		})
	})

	router.POST("/upload", func(c *gin.Context) {
		usecase.UploadImg(c)
	})

	router.Run(":8080")
}

ポイント

他のパッケージで実装した関数を別のパッケージで使用したい時

  1. 関数を実装したファイルがあるフォルダをimport
main.go
import (
	"fmt"

	"github.com/gin-gonic/gin"
	"next_go_app/backend/usecase"
)

2.関数を使用する際は【パッケージ名.関数名】の形で呼び出す

main.go
//usecaseがパッケージ名

usecase.UploadImg(c)

2. フロントから画像を送信

課題

  • webcamRef.current?.getScreenshot()で取得できる情報は画像のBase64形式のデータであるため、Blob形式に変換する必要がある

変換するための関数base64ToBlobをフロントで定義する

javascript/page.tsx
const base64ToBlob = (base64: string) => {
    //Base64文字列のデータ部分を取得
    const byteString = atob(base64.split(",")[1]);

    //MIMEタイプの取得
    const mimeString = base64.split(",")[0].split(":")[1].split(";")[0];

    //バイトデータを格納
    const ab = new ArrayBuffer(byteString.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ab], { type: mimeString });
  };

このコードの内容は難しいです。
簡単にまとめるとatob()でBase64をバイナリデータに加工し、UTF-16文字コードに変換します。その後、UTF-16の文字列を引数として、Blobに変換するという流れになります。

次にフロントからバックエンドにデータを送る実装です。

javascript/page.tsx
const sendImg = async () => {
    if (!url) {
      console.error("No image URL found");
      return;
    }

    const formData = new FormData();
    const blob = base64ToBlob(url);
    formData.append("file", blob, `${uuidv4()}.jpg`);

   try{
    await axios.post("http://localhost:8080/upload", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    });
   }
   catch (e) {
     console.error(e);
   }
  };

写真をformDataに入れてaxiosを用いることでバックエンドに送信しています。ちなみにaxiosはfetchよりもpostとかを簡単に実装できるライブラリです。

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0