【emscripten webassembly 传参传图片参数】

文章介绍了如何在HTML页面中使用JavaScript的FileReaderAPI处理文件上传,并利用OpenCV.js进行图像处理,包括读取文件、转换为ArrayBuffer和显示处理后的图片。
摘要由CSDN通过智能技术生成
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传示例</title>
</head>
<body>
<h1>文件上传示例</h1>
<form id="uploadForm">
    <input type="file" id="fileInput" name="file" accept="image/*">
    <button type="submit">上传文件</button>
    <img id="showimg" style="width:300px;height:399px"/>
    <img id="showimg1" style="width:300px;height:399px"/>
</form>
<script src="https://docs.opencv.org/4.5.0/opencv.js" type="text/javascript"></script>

<script>
    function fileToArrayBuffer(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();

            reader.onloadend = () => resolve(reader.result);
            reader.onerror = (e) => reject(new Error('Failed to convert file to ArrayBuffer'));

            reader.readAsArrayBuffer(file);
        });
    }


    function get_image(uInt8Array) {

        // var uInt8Array = new Uint8Array(arr_buffer)
        var i = uInt8Array.length;
        var binaryString = new Array(i);
        while (i--) {
            binaryString[i] = String.fromCharCode(uInt8Array[i]);
        }
        var data = binaryString.join('');

        var base64 = window.btoa(data);

        var url = "data:image/bmp;base64," + base64;
        // console.log(url)
        return url
    }

    Module = {};
    Module.onRuntimeInitialized = function () {


        console.log(Module._add(33, 33))

        console.log(Module._add(44, 33))
        // 获取文件输入框和提交按钮元素
        const fileInput = document.getElementById('fileInput');
        const submitButton = document.querySelector('button[type="submit"]');

        // 添加文件选择事件监听器
        fileInput.addEventListener('change', (event) => {
            const files = event.target.files;
            const file = event.target.files[0];
            console.log(file)
            const img = new Image()
            const reader = new FileReader(file)
            reader.onload = function (e) {
                img.src = e.target.result
                document.getElementById('showimg').src = e.target.result
                img.onload = async function () {
                    console.log("图片宽度:", img.width);
                    console.log("图片高度:", img.height);

                    var filetoarraybuffer = await fileToArrayBuffer(file)
                    // var pBuffer = Module._malloc(1000)//分配堆内存
                    // var ptr = allocate(filetoarraybuffer, 'i8');
                    var iyuv_size = file.size
                    var pBuffer = Module._malloc(iyuv_size)
                    console.log('pBuffer1', pBuffer)
                    var Data = Module.HEAPU8.subarray(pBuffer, pBuffer + iyuv_size);//堆内存绑定到视图对象

                    Data.set(new Uint8Array(filetoarraybuffer));
                    console.log('pBuffer2', pBuffer)
                    var ptr = pBuffer
                    var retPtr = Module._read_file(ptr, img.width, img.height);
                    console.log('88888----', retPtr)

                    var buf = new ArrayBuffer(iyuv_size);//通过二进制对象分配一块连续内存
                    var ayuv_data = new Uint8Array(buf);//二进制对象绑定到视图,通过视图对内存进行读写操作
                    // retPtr = pBuffer //test
                    var pYUV = retPtr
                    console.log('pYUV', pYUV)
                    ayuv_data.set(Module.HEAPU8.subarray(pYUV, pYUV + iyuv_size));
                    console.log(buf, 'ayuv_data==', ayuv_data)
                    console.log('pYUV2', pYUV)
                    document.getElementById('showimg1').src = get_image(ayuv_data)
                    setTimeout(function () {
                        Module._free(retPtr)
                        console.log('retPtr==', retPtr)
                    }, 2000)

                };

            }
            reader.onerror = function (e) {
                reject(e)
            }
            reader.readAsDataURL(file)
            // reader.readAsArrayBuffer(file)
            // 在这里可以对文件进行处理,例如检查文件类型、大小等
            // 假设要上传到服务器,可以使用fetch或axios等库发送请求
            // fetch('/upload', {
            //   method: 'POST',
            //   body: file,
            //   headers: {
            //     'Content-Type': 'multipart/form-data'
            //   }
            // }).then(response => {
            //   // 处理响应数据
            //   console.log('文件上传成功');
            // }).catch(error => {
            //   // 处理上传错误
            //   console.error('文件上传失败:', error);
            // });
        });

        // 添加提交按钮事件监听器
        submitButton.addEventListener('click', () => {
            // 触发文件输入框的文件选择事件,可选,如果不添加可能会因安全限制导致无法上传文件
            fileInput.click();
        });

    }
</script>
<script src="testimg.js"></script>
</body>
</html>

c++

//#include "opencv2/opencv.hpp"
#include <emscripten.h>
#include <emscripten/bind.h>
//#include <opencv2/highgui.hpp>
//#include <opencv2/imgproc.hpp>
//#pragma comment(lib,"D:/OpenCv/opencv/build/x64/vc16/lib/opencv_world480.lib")
using namespace emscripten;


// 压缩图片的函数
//emcc -L "D:/OpenCv/opencv/build/x64/vc16/lib"   testimg.cpp -o testimg.js -s WASM=1 -O3 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','allocate']" -s "EXPORTED_FUNCTIONS=['_malloc', '_free']"
 //emcc   testimg.cpp -o testimg.js -s WASM=1 -O3 -s "EXPORTED_FUNCTIONS=['_malloc', '_free']" --bind
 extern "C" {
     EMSCRIPTEN_KEEPALIVE
     unsigned char* read_file(unsigned char* inputImage,int width,int height) {

         return inputImage;
//         cv::Mat matImg = cv::Mat(height, width, CV_8UC3, inputImage);
//         cv::Mat shrink;
//	       cv::resize(matImg, shrink, cv::Size(100,100), 0, 0, cv::INTER_AREA);
//        return shrink.data;
     }
     EMSCRIPTEN_KEEPALIVE
     int add(int a, int b) {
		return a + b;
	}
 }




编译cpp得到js和wasm文件

emcc testimg.cpp -o testimg.js -s WASM=1 -O3 -s “EXPORTED_FUNCTIONS=[‘_malloc’,‘_free’]” --bind

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值