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: about 1 hour ago
JSON representation
Wasm video filter booth app written in Rust
- Host: GitHub
- URL: https://github.com/mtharrison/wasmbooth
- Owner: mtharrison
- License: mit
- Created: 2018-04-26T14:38:06.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-12-31T18:17:12.000Z (almost 5 years ago)
- Last Synced: 2024-10-27T07:20:15.712Z (13 days ago)
- Topics: image-processing, javascript, rust, webassembly
- Language: Rust
- Homepage: https://mtharrison.github.io/wasmbooth/
- Size: 191 KB
- Stars: 82
- Watchers: 3
- Forks: 15
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-starred - mtharrison/wasmbooth - Wasm video filter booth app written in Rust (rust)
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 serverThen 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 againIf 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.