Skip to content

An exploratory project in Rust for efficient viewing of large images in a browser, using Webassembly

License

Notifications You must be signed in to change notification settings

jnickg/rust-explorations

Repository files navigation

Simple Image Viewer

Written by: Nick Giampietro AKA giampiet (PSU) AKA jnickg (General)

Overview

A simple tiling & pyramid-based image viewer, powered by Webassembly and Rust.

Preview of the Simple Image Viewer SPA

This project contains a backend server capable of computing an image pyramid, tiling pyramid levels into arbitrary sizes, and brotli compressing tiles. They are then made available using a simple REST API. Results are stored in a MongoDB instance for persistence.

Because the library also compiles to Webassembly, the frontend is capable of running the above routines locally. This is currently not implemented, however.

The sample frontend uses Yew to create the single-page application users see in their browser. The canvas in the SPA samples from the computed image pyramid, rather than scaling a large source image. This means that zooming out, and panning at distant zoom levels, is much faster. This is especially noticeable with large images, where subsampling a 4K image proves to be a lot of work.

Developer Guide

Requirements

  • Docker & Docker Compose
  • Rust and rustup, nightly build channel, and wasm32-unknown-unknown toolchain installed
  • Cargo, and associated tools (e.g. cargo clippy, cargo watch, and trunk)
  • Bash-like terminal for running scripts

First-time Setup

Set up admin user credentials for the MongoDB container. The generated files live in the secrets directory, and need to be present in order for the docker container and server to function properly. Fresh clones, and any repositories that were recently git cleaned, will need to go through this step.

echo "myPassword" > secrets/mongo-pw.txt
echo "myAdminUser" > secrets/mongo-user.txt
# This is required because docker compose and/or official MongoDB image is jank and won't honor
# MONGO_INITDB_ROOT_PASSWORD_FILE environment variables, just MONGO_INITDB_ROOT_PASSWORD. To keep
# the passwords out of source control (out of docker-compose.yaml), we make an env file for the
# mongo image, which seems to work
./generate_mongo_env.sh
docker compose up --build -d mongodb --force-recreate

Building

Create binaries and docker images needed to run the server

rustup override set nightly # required for test infra
cargo build --release
docker compose build mongodb

Running

# This builds the frontend and backend and keeps them both updated live as files change.
# To run in debug mode, simply exclude --release
./run_site_dev.sh --release

Alternatively, you can run the launch commands manually:

  • docker compose up --build -d mongodb
  • cd frontend && trunk serve --release --proxy-backend=http://localhost:8081/api/v1 &
  • cd server && cargo watch -- cargo run --bin jnickg_tile_server $RELEASE_FLAG -- --host localhost --user admin --pass ../secrets/mongo-pw.txt --db-port 27017 --port 8081 --static-dir ../dist/ &

Note that you will need to manually kill the spawned processes by their PID when you are done, and run docker compose down mongodb to shutdown the MongoDB server.

Using

Cleaning

Clean the MongoDB instance of all data

docker compose down mongodb # In case the run scripts failed to kill it
sudo rm -rf ./mongo/db # We volume mount DB data so it persists between sessions. This clears local files

The following should not be necessary, but in order to rule out stale build artifacts during debug, the following can be run from the directory root:

rm -rf dist
cargo clean --verbose

Tasks

  • Image support (CRUD)
    • Format conversion for all supported ImageFormat mappings (GET with Content-Type header and/or file extension in path)
  • Matrix support (CRUD)
  • Matrix Math REST interface (dot product, add, subtract)
  • Image filtering/convolution with arbitrary kernel
  • Image Pyramid generation (Gaussian filter + strided subsampling)
  • Pyramid Tile generation ($\text{512}\times\text{512}$)
  • CLI tool for pyramid/tile generation
  • Brotli compression of tiled image pyramid
  • Persistent DB backend (MongoDB)
    • integrate Image support (Doc + GridFS)
    • integrate Matrix support (Doc) (Not needed)
    • integrate Pyramid support (Doc + Images)
    • integrate Tile support (Doc + Images)
  • Wasm support
    • Headless backend (Not needed)
    • In-browser frontend
  • Websocket support for long-running tasks (Stretch)
  • User interface

Support

Open an issue with a question or bug report, or feel free to open a pull request.

Credits

  • The glorious and infallable knock-knock repo was used as inspiration in terms of structure and crates used. Some code (especially middleware setup) may be similar.

About

An exploratory project in Rust for efficient viewing of large images in a browser, using Webassembly

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published