📸

Rust | egui を使って画像を差し替え、再描画させる

2024/06/23に公開

はじめに

本記事は前回の egui というクレートを使って外部の画像を表示させる記事の続編です。
Github 上の png ファイルを表示させ、さらにそれを再描画(他の画像に差し替える)をやっていければと思います。

https://zenn.dev/collabostyle/articles/54f81af6df6764

下準備

ここは前回とほとんど同じですが、
今回は、ランダムな id を生成して、それを使用して再度画像を取得し、描画したいと思いますので、
randクレートを追加しておきます。

Cargo.toml
[dependencies]
eframe = "0.27.2"
egui = "0.27.2"
egui_extras = { version = "0.27.2", features = ["default", "all_loaders"] }
image = { version = "0.25.1", features = ["jpeg", "png"] }
rand = "0.8.5"

randでランダムな数字を生成する時に参考とした記事です。
https://zenn.dev/termoshtt/books/b4bce1b9ea5e6853cb07/viewer/rand

画像の取得、再描画

コードを以下のようにしてみました。

main.rs
use rand::Rng;

fn main() -> Result<(), eframe::Error> {
    let options = eframe::NativeOptions {
        viewport: egui::ViewportBuilder::default().with_inner_size([600.0, 800.0]),
        ..Default::default()
    };

    eframe::run_native(
        "Pokemon Viewer",
        options,
        Box::new(|cc| {
            egui_extras::install_image_loaders(&cc.egui_ctx);
            Box::new(MyApp { id: 1 })
        }),
    )
}

#[derive(Default)]
struct MyApp {
    id: usize,
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            let img_url = format!("https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/home/{}.png", self.id);
            ui.add(egui::Image::new(img_url).sense(egui::Sense::click()));

            if ui.button("change pokemon").clicked() {
                self.id = rand::thread_rng().gen_range(1..=1025)
            }
        });
    }
}

画像下部にボタンを配置し、クリックイベントを発火させます。
そして、前述したrandを使って、ランダムな数字を生成して id を変更するといった処理になります。
gen_range()メソッドを使用することで、限定した数字を生成することができます。

ポケモンの全国図鑑の最小値は11、最大値は1025であることから数字を絞り込んでいます。
https://ja.wikipedia.org/wiki/全国ポケモン図鑑順のポケモン一覧

cargo runを実行後すると・・

ポケモン

このように、最近のパルデア地方のポケモンにも差し替えが可能です。

おわりに

画像の差し替え、再描画を実装しようとした時、
複雑な処理を入れないと実現出来ないと思っていましたが、意外にも?簡単に実装することができます。

思考したポイントは、初期値どうするか、ランダムな数字の生成、再描画の方法等でしたので、
比較的悩まずに実装できたと思います。
これらの内容は、egui を使った他の実装でも役立つところもあるかと思いますので、ぜひご参考に。

では!

コラボスタイル Developers

Discussion