I want to save image

I want to develop like this functions in web(emscripten)
1.Show a file save dialog.
2.Input file name and push save button
3.Save image to local device.
But I cannot get how to do this.
Do you know about this?

I cannot get how to show file save dialog in linux environment…

you can have a look at this example :

examples/input_output/fileOpenSaveDialogExample

Thank you.
I tried fileOpenSaveDialogExample in linux and emscripten
It worked in linux ,But It cannot work it in emscripten.
it show like this messaage

[notice ] ofxAppEmscriptenWindow: Got 1 display configs
[verbose] User hit cancel:
[verbose] User hit cancel:
[verbose] User hit cancel:

(when I pushed space ,it show" User hit cancel: " and no show a dialog every time)
I think It come from a lost of file permission,
if you know this reason ,please tell me it.

I don’t know how to add permissions in emscripten

These functions are not implemented in emscripten. You would need to implement them in html/javascript

Usually you add the html in the page where you show the application and call javascript funciotns from the the c++ side using emscripten_run_script or the EM_JS or EM_ASM macros: https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html

I wrote this code


void ofApp::saveImage(cv::Mat img){
#ifdef EMSCRIPTEN
    cout<<"EMSCRIPTEN"<<endl;
    EM_ASM(
    function ImageToBase64(img, mime_type) {
        // New Canvas
        var canvas = document.createElement('canvas');
        canvas.width  = img.width;
        canvas.height = img.height;
        // Draw Image
        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
        // To Base64
        return canvas.toDataURL(mime_type);
    }
    var b64 = ImageToBase64(img, "image/jpeg");
    window.open(b64);
    );
#else
    cout<<"LINUX"<<endl;
#endif
}

But This code cannot run .
It causes " img is not defined"
Do you know how to convert to cv::mat to javascript image data.?

no idea but you probably need to use a javascript blob or something similar to go from c++ data to javascript and then be able to save it

I solved to transport data from C->javascript.
like this:

#ifdef EMSCRIPTEN
#include <emscripten.h>

EM_JS(int, showImage, (cv::Mat img), {

          function ImageToBase64(img, mime_type) {
              // New Canvas
              var canvas = document.createElement('canvas');
              canvas.width  = img.width;
              canvas.height = img.height;
              // Draw Image
              var ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              // To Base64
              return canvas.toDataURL(mime_type);
          }

          var b64 = ImageToBase64(img, "image/jpeg");
          window.open(b64);
          return 0;
});

#endif


void ofApp::saveImage(cv::Mat img){
#ifdef EMSCRIPTEN
    cout<<"EMSCRIPTEN"<<endl;
    showImage(img);
#else
    cout<<"LINUX"<<endl;
#endif

}

But this code throw new error
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)

I think it must convert cv::mat to blob

I can set blob like this way
All is OK
and add LINK flg --bind.

std::vector<uchar> g_buffer;
int buffer_size(){
    return g_buffer.size();
}

uchar buffer_data(int pos){
    return g_buffer[pos];
}

#ifdef EMSCRIPTEN
#include <emscripten.h>
#include <emscripten/bind.h>






EMSCRIPTEN_BINDINGS(my_module) {

    emscripten::function("buffer_data", &buffer_data);
    emscripten::function("buffer_size", &buffer_size);
}

EM_JS(int, showImage, (), {

          function ImageToBase64(img, mime_type) {
              // New Canvas
              var canvas = document.createElement('canvas');
              canvas.width  = img.width;
              canvas.height = img.height;
              // Draw Image
              var ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              // To Base64
              return canvas.toDataURL(mime_type);
          }
          function debugBase64(base64URL){
              var newTab = window.open();
              newTab.document.body.innerHTML = '<img src="'+ base64URL +'" >';
          }


          console.log('Start');

          var size=Module.buffer_size();
          var uint8 = new Uint8Array(size);
          for(var i=0;i<size;i++){
              uint8[i]=Module.buffer_data(i);
          }
          var blob = new Blob([ uint8 ], { type: "image/png" });
          console.log('blob:'+blob);
          window.createImageBitmap(blob)
          .then(function(image) {
              var width = image.width;
              var height = image.height;
              console.log('ok'+image);
              var b64 = ImageToBase64(image, "image/jpeg");
              debugBase64(b64);
          })
          .catch(function(error) {
              console.log(error);
          });



          console.log('End');


      });

#endif



void ofApp::saveImage(cv::Mat img){
    cout<<"ookawa koui"<<endl;

    cv::imencode(".png", img, g_buffer);


#ifdef EMSCRIPTEN
    cout<<"EMSCRIPTEN"<<endl;
    showImage();
#else
    cout<<"LINUX"<<endl;
#endif

}

Is there an example somewhere how to implement an open / save dialog?
Edit: I found an Emscripten example for loading and saving files:


or
https://msorvig.github.io/qt-webassembly-examples/gui_localfiles/gui_localfiles.html
But I do not know if it could work with Open Frameworks Emscripten.