从aardio给web.view中传递二进制图片

Mr_MAO 1月前 738

aardio使用web.view库后,可以很方便的在aardio与html之间传递数据,如果是数字、字符串这些基本数据类型,web.view库自动就帮我们处理好了,不需要考虑两者之间数据类型的区别。如果是二进制文件(如图片),就不能直接传递了,一般通过转换为base64格式后传递到web.view的网页中。

import win.ui;
/*DSG{{*/
var winform = win.form(text="使用web.view显示图片";right=807;bottom=519)
winform.add(
button={cls="button";text="选择一张本地的图片,加载到web.view的网页中";left=24;top=16;right=464;bottom=60;dl=1;dt=1;z=1};
custom={cls="custom";left=24;top=72;right=784;bottom=496;db=1;dl=1;dr=1;dt=1;edge=1;z=2}
)
/*}}*/

import fsys.dlg;
import crypt.bin;
import web.view;
var htmlTemplate = /**
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body { margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100%; background-color: #f0f0f0 }
        #imgContainer { max-width: 100%; max-height: 100%; text-align: center; }
        #imgDisplay { max-width: 100%; box-shadow: 0 0 10px rgba(0,0,0,0.3); }
        #noImage { color: #888; font-family: Arial, sans-serif; font-size: 16px; }
    </style>
</head>
<body>
    <div id="imgContainer">
        <div id="noImage">↑ 请点击上方按钮选择图片</div>
        <img id="imgDisplay" style="display:none;"/>
    </div>
    <script>
        function displayImage(base64Data) {
            var imgDisplay = document.getElementById('imgDisplay');
            var noImage = document.getElementById('noImage');
            
            if(base64Data) {
                imgDisplay.src = base64Data;
                imgDisplay.style.display = '';
                noImage.style.display = 'none';
            } else {
                imgDisplay.style.display = 'none';
                noImage.style.display = '';
            }
        }
    </script>
</body>
</html>
**/

var wb = web.view(winform.custom);
wb.html = htmlTemplate;

winform.button.oncommand = function(id,event){
    var filePath = fsys.dlg.open("图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif||",,,winform.hwnd);
    if(!filePath) return;
    
    var buffer = string.load(filePath);
    if(!buffer) return;
    
    // 获取文件扩展名
    var ext = io.splitpath(filePath).ext;
    ext = string.replace(ext, ".", "");
    
    // 使用crypt.bin进行Base64编码
    var base64Data = crypt.bin.encodeBase64(buffer);
    
    // 构造data URI
    var mimeType = "image/" + (ext == "jpg" ? "jpeg" : ext);
    var dataUri = "data:" + mimeType + ";base64," + base64Data;
    
    // 调用JavaScript函数显示图片
    wb.doScript("displayImage('" + dataUri + "')");
}

winform.show();
win.loopMessage();

也可以使用cdp接口来实实现上述功能,方法比较讨巧,通过自动化操作网页上隐藏的input-file控件,实现二进制图片的加载。

import win.ui;
/*DSG{{*/
var winform = win.form(text="webview组件cdp自动化的应用举例";right=967;bottom=607)
winform.add(
button={cls="button";text="选择一张本地的图片,加载到web.view的网页中";left=24;top=16;right=384;bottom=63;z=2};
custom={cls="custom";left=16;top=80;right=960;bottom=584;border=1;edge=1;z=1}
)
/*}}*/

import web.view;
var wv = web.view(winform.custom);

wv.html = /**
<!doctype html>
<meta charset="utf-8">
<input type="file" style="display:none;">
<img id="localImage" src="" style="display:inline-block;;width:85vw;"/>
**/

import fsys.dlg;
winform.button.oncommand = function(id,event){
    var imgpath = fsys.dlg.open("图片文件|*.jpg;*.png;*.gif","打开一张图片")
    if(imgpath){
        //获取html页面input标签
        var file = wv.cdpWaitQuery(`input[type="file"]`);
        //设置input上传文件的路径
        wv.cdp("DOM.setFileInputFiles",{
            files = { imgpath };
            nodeId = file.nodeId;  
        })

        //获取html页面input标签
        var img = wv.cdpWaitQuery(`img[id='localImage']`);
        //给img标签设置src,将图片显示在img标签中
        wv.cdp("DOM.setAttributeValue",{
            name = "src";
            value = wv.eval(`window.URL.createObjectURL(  document.querySelector('input[type="file"]').files[0] )`);
            nodeId = img.nodeId;
        })
    }
}

winform.show();
win.loopMessage();

问了下AI,有没有更高效的往网页中传递二级制数据的方法,AI说还有一个很牛逼的webview.postMessage函数,但是aardio好像没有封装。

如果大家有好的实现方案,可以讨论分享一下~

最新回复 (7)
  • 光庆 1月前
    0 2

  • shzhbook 1月前
    0 3
    学习了,感谢分享!
  • Mr_MAO 19天前
    0 4

    官方在v39后给了一个往webview中传二进制的例子,写的很简洁!

    //自己照着官方例子写的
    import win.ui;
    /*DSG{{*/
    var winform = win.form(text="aardio form";right=791;bottom=527)
    winform.add(
    button={cls="button";text="显示一张本地图片";left=24;top=16;right=184;bottom=56;dl=1;dt=1;z=1};
    custom={cls="custom";text="自定义控件";left=24;top=64;right=760;bottom=504;db=1;dl=1;dr=1;dt=1;z=2}
    )
    /*}}*/
    
    import web.view;
    wv = web.view(winform.custom);
    
    import fsys.dlg;
    import gdip.bitmap;
    winform.button.oncommand = function(id,event){
        var imgpath = fsys.dlg.open("图像文件|*.jpg;*.bmp;*.gif;*.png","请选择一个图片")
        if(imgpath){
            wv.invoke("showImage",imgpath) 
        }    
    }
    
    wv.external = {
        getImageBuffer = function(imgpath){ 
            var bitmap = gdip.bitmap(imgpath);
            var buffer = bitmap.saveToBuffer("*.jpg")
            //var buffer = string.loadBuffer(imgpath)    //这样能正常显示gif
            return buffer;
        };
    }
    wv.html = /**
    <!doctype html>
    <meta charset="utf-8">
    <style>
    body {
        margin: 0;    padding: 0;
        width: 100vw;    height: 100vh;
        display: flex;
        justify-content: center;    align-items: center;
        overflow: hidden;
    }
    img {
        max-width: 100%;    max-height: 100%;
        object-fit: contain;
    }
    </style>
    <body>
    <img id="outImage">
    <script>
      async function showImage(path) {
        var nativeByteArray = await aardio.getImageBuffer(path); 
        const uint8Array = new Uint8Array(nativeByteArray);
        const blob = new Blob([uint8Array], { type: 'image/jpeg' });
        const imageUrl = URL.createObjectURL(blob);
        document.getElementById('outImage').src = imageUrl;
      } 
    </script> 
    <body>
    **/
    winform.show();
    win.loopMessage();


  • 光庆 19天前
    0 5
    Mr_MAO 官方在v39后给了一个往webview中传二进制的例子,写的很简洁!//自己照着官方例子写的 import&nbsp;win.ui; /*DSG{{*/ var&nbsp;win ...

    我也来一个另类的:

    import win.ui;
    /*DSG{{*/
    var winform = win.form(text="aardio form";right=791;bottom=527)
    winform.add(
    button={cls="button";text="显示一张本地图片";left=24;top=16;right=184;bottom=56;dl=1;dt=1;z=1};
    custom={cls="custom";text="自定义控件";left=24;top=64;right=760;bottom=504;db=1;dl=1;dr=1;dt=1;z=2}
    )
    /*}}*/
    
    import godking.resHtml
    var ht = godking.resHtml( /*资源目录*/,/*首页文件名*/,           `
               function(url){
                   var file = ..string.right(url,-6);
                   return ..string.load(file); 
               }
               `)
    var url = ht.url
    
    import web.view;
    wv = web.view(winform.custom);
    winform.show()
    
    import fsys.dlg;
    import gdip.bitmap;
    winform.button.oncommand = function(id,event){
        var imgpath = fsys.dlg.open("图像文件|*.jpg;*.bmp;*.gif;*.png","请选择一个图片")
        if(imgpath){
            wv.invoke(string.format("document.getElementById('outImage').src='%s'",url++"/"++inet.url.encode(imgpath)))
        }    
    }
    
    wv.html = /**
    <!doctype html>
    <meta charset="utf-8">
    <style>
    body {
        margin: 0;    padding: 0;
        width: 100vw;    height: 100vh;
        display: flex;
        justify-content: center;    align-items: center;
        overflow: hidden;
    }
    img {
        max-width: 100%;    max-height: 100%;
        object-fit: contain;
    }
    </style>
    <body>
    <img id="outImage">
    <body>
    **/
    
    winform.show();
    win.loopMessage();


  • Mr_MAO 19天前
    0 6

    庆大牛B,你这个竟然能正常显示Gif !~

  • niheibie 8天前
    0 7
    66666
返回