画像などのバイナリファイルを読み込む

Recipe ID: fs-003

ローカルファイルシステム上の画像、音声、PDF などのバイナリファイルを読み込む方法を紹介します。
読み込まれたデータは Uint8Array (バイト配列) として返されます。これを BlobObject URL に変換することで、<img> タグで表示したり、サーバーへアップロードしたりできます。

前提条件

このレシピを使用するには、@tauri-apps/plugin-fs プラグインが必要です。

1. プラグインのインストール

プロジェクトのルートディレクトリで以下のコマンドを実行してプラグインを追加します。

npm run tauri add fs

2. Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
  "permissions": [
    ...,
    {
      "identifier": "fs:allow-read-file",
      "allow": [{ "path": "$RESOURCE/**" }, { "path": "$APPLOCALDATA/**" }]
    }
  ]
}

※ 上記の例では $RESOURCEBaseDirectory.Resource)および $APPLOCALDATABaseDirectory.AppLocalData)配下の読み込みを許可しています。アクセスするディレクトリに応じて、パス変数を指定してください。スコープが設定されていないディレクトリにはアクセスできません。

1. フロントエンドから作成する (TypeScript)

@tauri-apps/plugin-fsreadFile 関数を使用します。

リソースディレクトリから画像を読み込んで表示する

アプリに同梱した画像ファイル(src-tauri/resources などに配置)を読み込み、画面上の <img> タグで表示する例です。

注意: リソースファイルにアクセスするには、tauri.conf.jsonbundle -> resources にファイルまたはディレクトリを登録する必要があります。
上記の設定の場合、src-tauri/assets ディレクトリを作成し、その中に logo.png などのファイルを配置してください。

// tauri.conf.json
{
  "bundle": {
    "resources": [
      // src-tauri/assets 配下のファイルをすべて含める
      "assets/*"
    ]
  }
}
import { readFile, BaseDirectory } from '@tauri-apps/plugin-fs';

async function loadImage() {
  try {
    // $RESOURCE/assets/logo.png を読み込む
    const contents = await readFile('assets/logo.png', {
      baseDir: BaseDirectory.Resource,
    });

    // Uint8Array を Blob に変換
    const blob = new Blob([contents], { type: 'image/png' });
    // Blob から Object URL を生成
    const url = URL.createObjectURL(blob);
    
    // img要素のsrcに設定
    const imgElement = document.getElementById('my-image') as HTMLImageElement;
    if (imgElement) {
      imgElement.src = url;
    }
  } catch (err) {
    console.error('画像の読み込みに失敗:', err);
  }
}

ユーザーデータを読み込む

アプリが保存したバイナリデータを読み込みます。

import { readFile, BaseDirectory } from '@tauri-apps/plugin-fs';

async function readUserData() {
  try {
    const data = await readFile('user_save.dat', {
      baseDir: BaseDirectory.AppLocalData,
    });
    console.log('読み込み成功. データサイズ:', data.byteLength);
    // data は Uint8Array なので、必要に応じて解析や加工を行います
  } catch (err) {
    console.error('エラー:', err);
  }
}

2. バックエンドから作成する (Rust)

Rust の標準ライブラリ std::fs を使用してバイナリファイルを読み込みます。

バイナリデータの読み込み

use std::fs;

// 返り値の Vec<u8> はフロントエンドでは Uint8Array (または number[]) として受け取れます
#[tauri::command]
fn read_binary_file(path: String) -> Result<Vec<u8>, String> {
    fs::read(path).map_err(|e| e.to_string())
}

リソースディレクトリからの読み込み

path().resource_dir() を使用してリソースディレクトリのパスを取得します。

use tauri::Manager;
use std::fs;

#[tauri::command]
fn read_resource_file(app: tauri::AppHandle) -> Result<Vec<u8>, String> {
    let resource_dir = app.path().resource_dir()
        .map_err(|e| e.to_string())?;
        
    let file_path = resource_dir.join("assets/image.png");
    
    fs::read(file_path).map_err(|e| e.to_string())
}

補足

  • readFile: readTextFile と異なり、Uint8Array (バイト配列) を返します。
  • 画像の表示: フロントエンドでバイナリ画像データを表示する場合、Blob オブジェクトを作成し、URL.createObjectURL() を使ってブラウザが扱える URL に変換するのが一般的です。Rust 側で読み込んだ場合も Uint8Array として渡されるため、同様の手順で表示できます。
  • Scope設定: fs:scope で許可されていないパスにアクセスしようとするとエラーが発生します (フロントエンドのみ)。