質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

解決済

React + Express + WebAssembly(Go) Go側で画像ファイルをbase64エンコード

tomoZQ
tomoZQ

総合スコア14

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

2回答

0リアクション

0クリップ

1068閲覧

投稿2022/09/12 05:32

前提

React + Expressで画像・動画投稿ができるシステムを作っております。
純粋にフロント側で画像をbase64に変換し、サーバー側へポストする方法で実装したのですが
base64への変換に時間がかかりすぎるためwasmを使ってみました。
wasmに繋いで適当にコンソール出力できるところまではできています。

実現したいこと

Reactから画像ファイルをwasmに渡し、wasmでbase64への変換を行いその変換結果をReactに返すということを行いたいです。

解決したいこと①Go側で画像ファイルが渡されているのかを確認できる方法を知りたい
解決したいこと②もし画像ファイルが渡されている場合どのようにエンコードすれば良いか。(os.Openに何を渡せば良いかが分かればなんとか行けそうな気がしています。)

発生している問題・エラーメッセージ

wasm側の関数を呼び出すことはできているがファイルが渡せているのか確認する方法がわからない。
ファイルを引数として受けれているのならGoでこのように受けたファイルをどのようにエンコードできるのかわからない。

該当のソースコード

wasm.js

javascript

const go = new window.Go() export default go

Form.jsx

javascript

import React, { useState } from 'react' import { TextField, Button, Typography, Paper } from '@material-ui/core'; import { useDispatch } from 'react-redux' import { createChat } from '../../../actions/chats'; import useStyles from './styles' import go from '../../../actions/wasm' const Form = ({ gossipId }) => { const classes = useStyles() const [chatData, setChatData] = useState({message: '', selectedFile: ''}) const user = JSON.parse(localStorage.getItem('profile')) const dispatch = useDispatch() const [ imageFile, setImageFile ] = useState({identify: '', file: null}) const reader = new FileReader const uploadFile = async () => { let val = null let sample = null reader.readAsDataURL(imageFile.file) reader.addEventListener('load', async () => { await WebAssembly.instantiateStreaming(fetch("/wasm/main.wasm"), go.importObject).then((result) => { go.run(result.instance) sample = window.test(imageFile.file) }).catch((err) => { console.log(err) }) val = reader.result.replace(/data:.*\/.*base64,/,'') dispatch(createChat({ ...chatData, name: user?.result?.name, gossip: gossipId, userId: user.result._id ? user.result._id : user.result.googleId, file: val, identify: imageFile.identify, test: sample })) }) } const handleSubmit = async (e) => { console.log('submit clicked') e.preventDefault() if (imageFile.file) { uploadFile() }else{ dispatch(createChat({ ...chatData, name: user?.result?.name, gossip: gossipId, userId: user.result._id ? user.result._id : user.result.googleId})) } clear() } const clear = () => { setChatData({message: '', selectedFile: ''}) setImageFile({identify: '', file: null}) } const fileSet = (e) => { const files = e.target.files const file = files[0] const time = new Date().getTime() const identify = `chats/${user?.result?._id ? user?.result?._id : user?.result?.googleId}_${time}_${file.name}` setImageFile({identify: identify, file: file}) setChatData({ ...chatData, selectedFile: identify }) } if(!user?.result?.name){ return ( <Paper className={classes.chatFormPaper}> <Typography variant='h6' align='center'> Please Sign In to Create Your Own Chat and Like Other's Chat </Typography> </Paper> ) } return ( <Paper className={classes.chatFormPaper}> <form className={classes.form} autoComplete='off' noValidate onSubmit={ handleSubmit }> <Typography className={classes.formTitle} variant='h6' align='center'>Let's exchange opinions</Typography> <TextField className={classes.messageForm} name='message' variant='outlined' label='Message' multiline rows={3} fullWidth value={chatData.message} onChange={e => setChatData({ ...chatData, message: e.target.value })} /> <div className={classes.imageForm}> <input type='file' multiple={false} onChange={(e) => fileSet(e)}/> </div> <Button variant='contained' color='primary' size="large" type="submit" fullWidth>Submit</Button> </form> </Paper> ) } export default Form

main.go

go

// コメントアウト部分が実行できればと考えています。 package main import ( "syscall/js" "fmt" // "os" // "io/ioutil" // "encoding/base64" ) func test(this js.Value, vs []js.Value) interface{}{ fmt.Println(this) fmt.Println(vs) fmt.Println(vs[0]) // f, err := os.Open(vs[0].String()) // if err != nil { // panic(err) // } // defer f.Close() // b, _ := ioutil.ReadAll(f) // out, _ := os.Create("out") // base64.NewEncoder(base64.StdEncoding, out).Write(b) return "hogehoge" } func setFuncs(){ js.Global().Set("test", js.FuncOf(test)) } func main () { fmt.Println("App assembly process start") setFuncs() done := make(chan struct{}, 0) <-done }

試したこと

wasm側で受けとった引数のコンソール出力
イメージ説明

実際に上記main.goのコメントアウトを外して動作を確認
main.go

go

package main import ( "syscall/js" "fmt" "os" "io/ioutil" "encoding/base64" ) type General interface {} func test(this js.Value, vs []js.Value) interface{}{ // fmt.Println(this) // fmt.Println(vs) // fmt.Println(vs[0]) f, err := os.Open(vs[0].String()) if err != nil { panic(err) } defer f.Close() b, _ := ioutil.ReadAll(f) out, _ := os.Create("out") base64.NewEncoder(base64.StdEncoding, out).Write(b) return "hogehoge" } func setFuncs(){ js.Global().Set("test", js.FuncOf(test)) } func main () { fmt.Println("App assembly process start") setFuncs() done := make(chan struct{}, 0) <-done }

結果

イメージ説明

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

tomoZQ

2022/09/19 10:00 編集

前提の base64への変換に時間がかかりすぎるためwasmを使ってみました。 →base64への変換に時間がかかっていたわけではありませんでした。 画像ファイルを渡すのではなくbase64エンコードされた文字列を渡し、文字列の加工をwasmで行う方法で実装しました。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。