配列をそのままフロントエンド(HTML+Javascript)に転送する。
// 返却用の構造体のために必要 use serde::Serialize; // 値を返す構造体 #[derive(Serialize)] struct ImageData{ image:Vec<u8>, width:u32, height:u32, } // 画像と情報を返す関数 #[tauri::command] fn get_image() -> ImageData { let width:u32 = 256; let height:u32 = 400; // 画像生成 let mut imgrgb = Vec::<u8>::new(); for x in 0..width{ let r = (x % height) as u8; for _ in 0..height{ imgrgb.push(((r as usize ) % 256) as u8); imgrgb.push(0); imgrgb.push(0); } } // 返却 ImageData { image: imgrgb, width: width, height: height, } } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![get_image]) // get_image関数を登録 .run(tauri::generate_context!()) .expect("error while running Tauri application"); }
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Rust+Tauri画像表示</title> <style> canvas#mycanvas { border: 1px solid #000; } </style> <script type="module" src="/main.js" defer></script> </head> <body> <h1>Rust+Tauri画像表示</h1> <button id="ButtonLoadImage">画像表示</button> <canvas id="mycanvas" width="640" height="480"></canvas> </body> </html>
const { invoke } = window.__TAURI__.core; document.getElementById('ButtonLoadImage').addEventListener('click',async()=>{ const mycanvas = document.getElementById('mycanvas'); const ctx = mycanvas.getContext('2d'); const ImageData = await window.__TAURI__.core.invoke("get_image"); const rustArray = new Uint8Array(ImageData.image); // RGB8の配列 const width = ImageData.width; const height = ImageData.height; // Canvasサイズを調整 mycanvas.width = width; mycanvas.height = height; // キャンバスの画像データを作成 const CanvasImageData = ctx.createImageData(width,height); // キャンバスに与えるデータへの参照を取得 const tmp = CanvasImageData.data; // Rust側がRGBを返すので、RGBA形式で格納 for(let i=0;i<width*height;i++){ tmp[i*4+0] = rustArray[i*3+0]; tmp[i*4+1] = rustArray[i*3+1]; tmp[i*4+2] = rustArray[i*3+2]; tmp[i*4+3] = 255; } ctx.putImageData(CanvasImageData,0,0); });
上ではデータをrgbで送ったため、Canvasが対応するrgbaに変換するためにforを回す必要があったが、rgbaであれば直接コピーできる。
const { invoke } = window.__TAURI__.core; document.getElementById('ButtonLoadImage').addEventListener('click',async()=>{ const mycanvas = document.getElementById('mycanvas'); const ctx = mycanvas.getContext('2d'); const ImageData = await window.__TAURI__.core.invoke("get_image"/*,{index}*/ ); const rustArray = new Uint8Array(ImageData.image); // RGB8の配列 const width = ImageData.width; const height = ImageData.height; // Canvasサイズを調整 mycanvas.width = width; mycanvas.height = height; // キャンバスの画像データを作成 const CanvasImageData = ctx.createImageData(width,height); // キャンバスにRustから受け取ったデータをセット CanvasImageData.data.set(rustArray); ctx.putImageData(CanvasImageData,0,0); });