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

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

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

Emscripten は JavaScript に変換するコンパイラです。 C/C++ から生成される LLVM ビットコードをJavaScript に変換します。

Q&A

解決済

1回答

714閲覧

webassemblyでの画像をCからjavascriptにもちこむ方法について

kokawa2003

総合スコア217

Emscripten

Emscripten は JavaScript に変換するコンパイラです。 C/C++ から生成される LLVM ビットコードをJavaScript に変換します。

0グッド

0クリップ

投稿2018/10/13 03:13

編集2018/10/13 04:18

webassemblyでCでプログラミングしています。
Cとjavascriptの変換で苦しんでおります
https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html
を読んで以下の関数を作りました。

C

1void showImage(cv::Mat img){ 2#ifdef EMSCRIPTEN 3 cout<<"EMSCRIPTEN"<<endl; 4 5 EM_ASM( 6 function ImageToBase64(img, mime_type) { 7 // New Canvas 8 var canvas = document.createElement('canvas'); 9 canvas.width = img.width; 10 canvas.height = img.height; 11 // Draw Image 12 var ctx = canvas.getContext('2d'); 13 ctx.drawImage(img, 0, 0); 14 // To Base64 15 return canvas.toDataURL(mime_type); 16 } 17 18 var b64 = ImageToBase64(img, "image/jpeg"); 19 window.open(b64); 20 ); 21#else 22 cout<<"LINUX"<<endl; 23#endif 24 25}

これ実行すると
ImageToBase64のところで " img is not defined"
と言われて実行エラーを出してしまいます。

書いているときから思っていたがcv::matをそのままjavascriptにもちこむのはやはりNGらしいです。

それではどうやってもちこんだらいいのでしょうか?
なにかJavascriptのblobかなにかに変換する方法を知りませんか?

その後とりあえず持ちこむことは成功して

C

1 2#ifdef EMSCRIPTEN 3#include <emscripten.h> 4 5EM_JS(int, showImage, (cv::Mat img), { 6 7 function ImageToBase64(img, mime_type) { 8 // New Canvas 9 var canvas = document.createElement('canvas'); 10 canvas.width = img.width; 11 canvas.height = img.height; 12 // Draw Image 13 var ctx = canvas.getContext('2d'); 14 ctx.drawImage(img, 0, 0); 15 // To Base64 16 return canvas.toDataURL(mime_type); 17 } 18 19 var b64 = ImageToBase64(img, "image/jpeg"); 20 window.open(b64); 21 return 0; 22}); 23 24#endif 25 26 27void ofApp::saveImage(cv::Mat img){ 28#ifdef EMSCRIPTEN 29 cout<<"EMSCRIPTEN"<<endl; 30 showImage(img); 31#else 32 cout<<"LINUX"<<endl; 33#endif 34 35}

みたいな感じのですが今度はjavascriptでエラーを出してしまいます。
こんな感じです。
Uncaught TypeError: Failed to execute ‘drawImage’ on ‘CanvasRenderingContext2D’: The provided value is not of type ‘(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)’
at ImageToBase64 (:6931/OFNewPlayer.js:1)
at _showImage (:6931/OFNewPlayer.js:1)

これからするとやはり型が違うらしい。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

分かりました。コツはmatをPNGデータにしてjavascriptのblobに持ち込むことです。
C->Javascriptの通信はBINDで行います
リンクフフラグに--bind が要ります

C

1std::vector<uchar> g_buffer; 2int buffer_size(){ 3 return g_buffer.size(); 4} 5 6uchar buffer_data(int pos){ 7 return g_buffer[pos]; 8} 9 10#ifdef EMSCRIPTEN 11#include <emscripten.h> 12#include <emscripten/bind.h> 13 14 15 16 17 18 19EMSCRIPTEN_BINDINGS(my_module) { 20 21 emscripten::function("buffer_data", &buffer_data); 22 emscripten::function("buffer_size", &buffer_size); 23} 24 25EM_JS(int, showImage, (), { 26 27 function ImageToBase64(img, mime_type) { 28 // New Canvas 29 var canvas = document.createElement('canvas'); 30 canvas.width = img.width; 31 canvas.height = img.height; 32 // Draw Image 33 var ctx = canvas.getContext('2d'); 34 ctx.drawImage(img, 0, 0); 35 // To Base64 36 return canvas.toDataURL(mime_type); 37 } 38 function debugBase64(base64URL){ 39 var newTab = window.open(); 40 newTab.document.body.innerHTML = '<img src="'+ base64URL +'" >'; 41 } 42 43 44 console.log('Start'); 45 46 var size=Module.buffer_size(); 47 var uint8 = new Uint8Array(size); 48 for(var i=0;i<size;i++){ 49 uint8[i]=Module.buffer_data(i); 50 } 51 var blob = new Blob([ uint8 ], { type: "image/png" }); 52 console.log('blob:'+blob); 53 window.createImageBitmap(blob) 54 .then(function(image) { 55 var width = image.width; 56 var height = image.height; 57 console.log('ok'+image); 58 var b64 = ImageToBase64(image, "image/jpeg"); 59 debugBase64(b64); 60 }) 61 .catch(function(error) { 62 console.log(error); 63 }); 64 65 66 67 console.log('End'); 68 69 70 }); 71 72#endif 73 74 75 76void ofApp::saveImage(cv::Mat img){ 77 cout<<"ookawa koui"<<endl; 78 79 cv::imencode(".png", img, g_buffer); 80 81 82#ifdef EMSCRIPTEN 83 cout<<"EMSCRIPTEN"<<endl; 84 showImage(); 85#else 86 cout<<"LINUX"<<endl; 87#endif 88 89}

投稿2018/10/21 16:10

kokawa2003

総合スコア217

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問