Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/mtharrison/wasmbooth

Wasm video filter booth app written in Rust
https://github.com/mtharrison/wasmbooth

image-processing javascript rust webassembly

Last synced: 2 months ago
JSON representation

Wasm video filter booth app written in Rust

Lists

README

        

![WASMBOOTH](https://raw.githubusercontent.com/mtharrison/wasmbooth/master/public/logo.png)

## Video effect booth written in Rust and WebAssembly

Play with it here: https://mtharrison.github.io/wasmbooth/

### Aim

I wrote this purely to teach myself more about both Rust and WebAssembly and how to use the two together. The aim of this is definitely _not_ to show off the performance of wasm. I haven't benchmarked or compared this to a pure JS implementation but I wouldn't be surprised if it were slower because it copies all the ImageData from canvas into the wasm linear memory on every frame. Additionally it uses convolutional image processing for a few of the effects, which aren't the most efficient algorithms but are elegant and easy to write/understand.

### How it works

The front end is usual HTML, CSS, JS. It streams your webcam into an offscreen video element, which is then written to a hidden canvas. On each frame we grab the image data from the canvas and write it into WebAssembly's linear memory at a pre-determined offset. We then call a WebAssembly function that will process those pixels with our chosen filters. Finally, we construct a new ImageData object and put it on a visible canvas.

To capture a still, we write the visible canvas data into a premade template.

The wasm module exposes 2 functions to JavaScript. One tells the module to allocate enough space to hold all our pixel data and returns a pointer, which is a simple integer offset in the wasm linear memory. The other function takes that pointer and the dimensions of the image, along with our chosen filters.

- `lib` - Contains the frontend JS which will be bundled into public/bundle.js by webpack
- `public` - Everything that will be served up to the browser including compiled wasm module
- `src` - The Rust source code which will be compiled to wasm

### Usage

To simply use the app, run the following:

- `npm install --production` to install hapi (to serve the site)
- `npm start` to start a server

Then browse to `http://localhost:4000`

If you want to change JS inside lib, you should run:

- `npm install` to webpack
- `npm run build-js` after to bundle the JS again

If you want to change Rust, you should run:

- `npm run build-wasm` to recompile the .wasm module. You will need nighty Rust and the wasm target installed for this. There's a [good explanation here](https://rust-lang-nursery.github.io/rust-wasm/setup.html)

There are some Rust tests, to run them run:

- `npm test` or `cargo test`

#### Using Docker

Build the image:

- `docker build -t mtharrison/wasmbooth .`

Run the image (on port 4000):

- `docker run -p 4000:4000 mtharrison/wasmbooth`

#### Using Docker with docker-compose

```
docker-compose up --build
```

### Contributing

PRs welcome to improve the code or approach or to add more effects, this is all about learning! I'm a newbie to both Rust and wasm so please open an issue if you think there's something I missed or could have done better.