yikegaya’s blog

仕事関連(Webエンジニア)と資産運用について書いてます

Go + WebAssemblyでアップロードされた画像のファイルを取得する

前回作った雛形をベースにWebAssemblyで画像処理サービスを作りたいと思い、とりあえずinputタグでアップロードしたファイルのサイズを取得してconsoleに出してみました。

書いたコード

index.html

<!DOCTYPE html>
<html>
<head>
    <title>WebAssembly File Size</title>
</head>
<body>
    <h1>WebAssembly File Size</h1>
    <input type="file" id="fileInput" accept="image/*">
    <script src="/js/wasm_exec.js"></script>
    <script>
        const go = new Go();

        WebAssembly.instantiateStreaming(fetch("/wasm/main.wasm"), go.importObject)
            .then(result => {
                go.run(result.instance);

                const fileInput = document.getElementById('fileInput');
                fileInput.addEventListener('change', function(event) {
                    const file = event.target.files[0];
                    if (file) {
                        getFileSize(file);
                    }
                });
            })
            .catch(err => {
                console.error(err);
            });
    </script>
</body>
</html>

main.go

package main

import (
    "fmt"
    "syscall/js"
)

func getFileSize(this js.Value, args []js.Value) interface{} {
    if len(args) != 1 {
        return nil
    }

    file := args[0]
    size := file.Get("size").Int()

    fmt.Printf("Uploaded File Size: %d bytes\n", size)

    return nil
}

func main() {
    c := make(chan struct{}, 0)

    js.Global().Set("getFileSize", js.FuncOf(getFileSize))

    <-c
}

Goでjs.Valueと[]js.Valueを引数に持ちinterface{}(any)を返す関数を作る。ここはお決まりらしい syscall/jsパッケージのjs.Global()でGoの関数をjs側に登録できる。

同じような仕組みでGoとJSで変数やDOMもやりとりできるっぽい