Expand description
Deep Zoom image rendering for 2D Bevy scenes.
bevy_deepzoom allows streaming Deep Zoom Image
(DZI) pyramids
into Bevy scenes by attaching DeepZoom components to Camera2d entities.
§Quick start
Add DeepZoomPlugin to your app and a DeepZoom component to your Camera2d.
use bevy::prelude::*;
use bevy_deepzoom::{DeepZoom, DeepZoomConfig, DeepZoomInitialView, DeepZoomPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(DeepZoomPlugin)
.add_systems(Startup, spawn_camera)
.run();
}
fn spawn_camera(mut commands: Commands) {
let config = DeepZoomConfig::new("assets/map/tiles.dzi", "assets/map/tiles_files")
.with_initial_view(DeepZoomInitialView::FitWidth)
.with_zoom_level_bias(1)
.with_max_concurrent_tile_loads(8);
commands.spawn((
Camera2d,
DeepZoom::from_config(config),
));
}The plugin
- loads the .dzi manifest
- derives the required tile zoom level from the camera projection scale
- streams in visible tiles for that level
- despawns tiles that are out of view or too high res for the camera scale
- clean up tiles when their owning camera is removed
§Asset layout
bevy_deepzoom expects a .dzi manifest and matching tile directory, typically:
assets/map/tiles.dzi
assets/map/tiles_files/
assets/map/tiles_files/0/0_0.jpeg
assets/map/tiles_files/1/0_0.jpeg
assets/map/tiles_files/8/12_4.jpeg§Generating a pyramid from a source image
To create new DZI assets, libvips dzsave works well. e.g.:
vips dzsave "source.png" "tiles" \
--layout dz \
--tile-size 256 \
--overlap 0 \
--depth onepixel \
--suffix ".jpeg[Q=90]"§Pyramid depth
DeepZoomPyramidDepth should be set based on the libvips dzsave --depth ... value used
when generating the DZI assets.
§Tuning sharpness and request volume
DeepZoomConfig::with_zoom_level_bias controls how aggressively the viewer prefers sharper
tiles.
A higher value loads higher-resolution levels sooner.
DeepZoomConfig::with_max_concurrent_tile_loads limits how many tile loads are allowed to be
in flight for a viewer at once. Reduce this if you get rate limited or experience performance
issues when loading many tiles in parallel.
§Events
Use DeepZoomLoaded to run app-specific setup once the .dzi is loaded.
Use DeepZoomLoadFailed to react to failed loads.
use bevy::prelude::*;
use bevy_deepzoom::{DeepZoomLoadFailed, DeepZoomLoaded};
fn on_deepzoom_loaded(
loaded: On<DeepZoomLoaded>,
mut cameras: Query<&mut Transform, With<Camera2d>>,
) {
let Ok(mut transform) = cameras.get_mut(loaded.event().0) else {
return;
};
transform.translation.z = 10.0;
}
fn on_deepzoom_load_failed(failed: On<DeepZoomLoadFailed>) {
let entity = failed.event().0;
let reason = &failed.event().1;
}Modules§
- dzi_
asset_ loader - Loader for the .dzi file format.
Structs§
- Deep
Zoom - Attach this to a
Camera2dentity. - Deep
Zoom Config - Deep
Zoom Load Failed - Triggered when a .dzi manifest fails to load.
- Deep
Zoom Loaded - Triggered when a .dzi manifest finishes loading.
- Deep
Zoom Plugin
Enums§
Constants§
- DEFAULT_
MAX_ CONCURRENT_ TILE_ LOADS - Default maximum number of concurrent in-flight tile loads.
- DEFAULT_
ZOOM_ LEVEL_ BIAS - Default number of zoom levels to bias toward sharper tiles.
Functions§
- fit_
width_ scale - Computes the
Camera2dscale required to fit the full image width in view. - loaded_
dzi - Returns the loaded .dzi.
Type Aliases§
- TileId
(zoom_level, x, y)identifier for a tile.