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");
}