スポンサーリンク

Rust+Tauriで画像を表示してみる

画像を高速に表示しようとするとWebGLを使うのがいいらしいが、いろいろと手間なので、まずはRust側でbase64に変換してimgに設定する方法を試す。高いフレームレートが要求される用途でなければ、十分に機能する。

バックエンド

main.rs

use base64::{engine::general_purpose, Engine as _};
use std::io::Cursor;
use image::codecs::png::PngEncoder;
use image::ImageEncoder;

// 返却用の構造体のために必要
use serde::Serialize;

// 値を返す構造体
#[derive(Serialize)]
struct ImageData{
    image:String,
    width:u32,
    height:u32,
}

// 画像と情報を返す関数
#[tauri::command]
fn get_image(index: usize) -> 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 y in 0..height{
            imgrgb.push(((r as usize * index) % 256) as u8);
            imgrgb.push(0);
            imgrgb.push(0);
        }
    }

    // PNGデータにエンコード
    // RGB配列 → PNG形式への変換
    let mut buffer = Cursor::new(Vec::new());
    let encoder = PngEncoder::new(&mut buffer);
    encoder.write_image(
        &imgrgb,
        width, height,
        image::ColorType::Rgb8
    ).unwrap();

    // Base64エンコードして返す
    // PNG形式 → Base64表現への変換
    let base64_image = general_purpose::STANDARD.encode(buffer.get_ref());

    // フロントエンドでimgタグに設定できる形式にする
    let img =format!("data:image/png;base64,{}", base64_image);

    // 返却
    ImageData {
        image: img,
        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");
}

Cargo.toml

[package]
name = "my1st_tauri"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-shell = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

image = "0.24"
base64 = "0.21"

フロントエンド

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Rust+Tauri画像表示</title>
</head>
<body>
  <h1>Rust+Tauri画像表示</h1>
  <img id="image-viewer" alt="Image Viewer" style="border: 1px solid black; width: 256px; height: 256px;">
  <p>左右キーで再読み込み</p>

  <script>
    let currentIndex = 0;

    async function updateImage(index) {
    
      // Rustから画像データを取得
      const imageData = await window.__TAURI__.core.invoke("get_image", { index });

      imageview = document.getElementById("image-viewer"); // 表示領域の取得
      imageview.src = imageData.image; // 画像を設定
      imageview.style.width = `${imageData.width}px`; // 画像の幅を設定
      imageview.style.height = `${imageData.height}px`; // 画像の高さを設定
    }

// 初期画像を読み込み updateImage(currentIndex);
    // キーイベントリスナー
    document.addEventListener("keydown", (event) => {
      if (event.key === "ArrowRight") {
        currentIndex++;
        updateImage(currentIndex);
      } else if (event.key === "ArrowLeft") {
        currentIndex = Math.max(0, currentIndex - 1);
        updateImage(currentIndex);
      }
    });
    
  </script>
</body>
</html>

コメントを残す

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

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


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