Tauri JavaScript使用自定义协议获取Rust端返回的二进制数据

JavaScript:
  var startTime = 0;
  var endTime = 0;
  var totalFrames = 0;
  var image = null;
  var getNewImg = function() {
    const fpstext = document.getElementById("fps");
    // var imgobj = document.getElementById("testimg");
    // var url = null;
    const imgcanvas = document.getElementById("imgcanvas");
    const ctx = imgcanvas.getContext("2d");
    // imgobj.onload = () => {
    //   totalFrames++;
    //   endTime = new Date().valueOf();
    //   var useTime = endTime - startTime;
    //   fps = totalFrames * 1000 / useTime;
    //   fpstext.innerText = fps;

    //   // 不再需要读取该 blob,因此释放该对象
    //   URL.revokeObjectURL(url);

    //   setTimeout(getNewImg, 0);
    // };
    //const requestUrl = "imgrawdata://localhost?n=" + totalFrames + "&b2";
    const requestUrl = "https://imgrawdata.localhost/?n=" + totalFrames + "&b2";
    //const requestUrl = "http://127.0.0.1:8080/img.jpg?n=" + totalFrames;
    //obj.src = requestUrl;
    const request = new Request(requestUrl, {
      method: "GET"
    });
    // taurihttp.fetch(requestUrl, {
    //   method: 'GET', 
    //   responseType : taurihttp.ResponseType.Binary
    // })
    if (startTime == 0) {
      startTime = new Date().valueOf();
    }
    fetch(request)
    // .then((response) => {})
    .then((response) => response.blob())
    .then((blob) => {
      //  url = URL.createObjectURL(blob);
      //  imgobj.src = url;
      blob.arrayBuffer().then(buffer=>{
        var array = new Uint8ClampedArray(buffer);
        if (image == null) {
          image = new ImageData(array, 5120, 2880);
          //image = new ImageData(array, 2000, 1125);
        } else {
          image.data = array;
        }
        ctx.putImageData(image, 0, 0);

        totalFrames++;
        endTime = new Date().valueOf();
        var useTime = endTime - startTime;
        fps = totalFrames * 1000 / useTime;
        fpstext.innerText = fps;

        setTimeout(getNewImg, 0);
      });
    })
    .catch((error) => {
      //console.error(error);
      //setTimeout(getNewImg, 0);
    });
  };
  setTimeout(getNewImg, 100);

HTML:
<p id="fps"></p>
<img id="testimg" src="" />

Rust:
use tauri::http::{header, ResponseBuilder};
use std::fs::{self, read};
use image::io::Reader as ImageReader;

static mut RGBA_IMG_DATA: Vec = vec![];

fn main() {
  tauri::Builder::default()
...
  .register_uri_scheme_protocol("imgrawdata", |app, request| {
      let res_not_img = ResponseBuilder::new()
        .status(404)
        .body(Vec::new());
      if request.method() != "GET" { return res_not_img; }
      let uri = request.uri();
      let start_pos = match uri.find("?n=") {
        Some(_pos) => _pos + 3,
        None => return res_not_img,
      };
      let end_pos = match uri.find("&") {
        Some(_pos) => _pos,
        None => return res_not_img,
      };
      let entry_num: usize = match &uri[start_pos..end_pos].parse() {
        Ok(_i) => *_i,
        Err(_) => return res_not_img,
      };
      println!("Request: n={}", entry_num);
      if unsafe { RGBA_IMG_DATA.len() } == 0 {
        let target_file = "E:\\tauri-app\\img.jpg";
        let img = image::open(target_file).unwrap();
        let rgba_img = image::DynamicImage::ImageRgb8(img.into()).into_rgba8();
        unsafe { RGBA_IMG_DATA = rgba_img.to_vec() };
      }
      println!("RGBA_IMG_DATA len:{}", unsafe { RGBA_IMG_DATA.len() });
      let local_img = 
        if unsafe { RGBA_IMG_DATA.len() } != 0 {
          tauri::http::ResponseBuilder::new()
            .header("Access-Control-Allow-Origin", "*")
            .header("ETag", entry_num.to_string())
            .header("Cache-control", "no-store")
            .mimetype("application/octet-stream")
            .header("Content-Length", unsafe { RGBA_IMG_DATA.len() })
            .status(200)
            .body(unsafe { RGBA_IMG_DATA.clone() })
      } else {
        res_not_img
      };
      local_img
  })
  .run(tauri::generate_context!())
  .expect("error while running tauri application");
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

3 × 5 =