スポンサーリンク

Rust+Tauriで画像を表示してみる(2) 配列で転送

配列をそのままフロントエンド(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");
}

main.html

<!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>

main.js

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

});

データがRGBAの場合

上ではデータを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);

});

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: