Svelte for the app ui
Rust for handling image processing, compiled to WASM using wasm-pack
rawler Raw image processing library, handles decoding image data and metadata, performs basic processing i.e. demosaicing, and provides a RawDevelop
module for further developing the raw data.
image Image library, which provides many useful utilisies for manipulating images - decoding, encoding etc... Works in conjunction with rawler
console_error_panic_hook brilliant library for surfacing panic messages from rust, straight to the javascript console
wasm_logger another great library for binding the log
create to the browser console
comlink A small RPC library for Web Workers
Goto: https://excalidraw.com/
Then, via the hamburger menu, click Open, and open system-diagram.excalidraw
This can be setup using devbox, to enter a pre-configured shell environment:
devbox shell
pnpm dev
This will first run pnpm build:wasm
to build the wasm module, then, it will start the Svelte dev server.
as part of
pnpm build:wasm
, the WASM files are output intosrc/lib/raw-processor
, allowing for the Svelte code (on in this case the worker files) to import the WASM code.
raw-processor/
āāā lib.rs - š¦ Main entry point to the rust logic for handling image processing
src/ - ā” Svelte application source code
āāā lib/ - components, state etc... general UI code can be found here
āāā raw-processor/ - š¦ š¦ The compiled WASM code - this will exist upon running `pnpm build:wasm`
āāā components/ - UI components
āāā workers/ - Web Worker files
āāā routes/ - where the pages are defined
devbox.json - š Defining the devbox development environment i.e. rust, node
Cargo.toml - š¦ Where the rust wasm module is configured (dependencies)
To update the rust raw processing module, and the exposed methods (that can be used in javascript), edit raw-processor/lib.rs
, or any related .rs
file inside of raw-processor/
Changes to the UI can be made inside of the src
directory
To compile to wasm run
pnpm build:wasm
wasm-pack
to compile to a wasm targetCargo.toml
src/lib/raw-processor/
init
. This will fetch the wasm binary and instantiate it.The simplest, bug-free way of consuming the WASM module was to simply copy it into the Svelte source code src/lib/raw-processor
In doing so, I can simply import the WASM Javascript file, without relying on Vite to know how to properly link the file, as was the case when trying:
pnpm link
wasm-bindgen-rayon
follwing setup as described in their README
This would be ideal, however, my attempts to implement this ran into some issues which I struggled to address. So the solution for now is not optimised for speed.
Commutative: involving the condition that a group of quantities connected by operators gives the same result whatever the order of the quantities involved, e.g. a Ć b = b Ć a
A question that may arise when building an image editor, is how can we apply the same operations, regardless of order, and yield the same result. This is the behaviour in which the user will expect.
e.g.
If red pixel value is 100... The user first applies 1.5x exposure, and then +20 red. The final pixel value is 170 ((100 x 1.5) + 20).
But if the user applies +20 red, then 1.5x exposure. The final pixel value is 180 ((100 + 20) x 1.5).
The solution is simple, the user applies the operations in any order, but under the hood, the image processor will always apply the operations in the same order. This is what other editors such as Lightroom, Rawtherapee etc... do in order to provide consistency in the operations.
rawloader
and imagepipe
by pedrocr, for processing the raw files. However, this was very quickly replaced with rawler
as rawler
was less of a black box and provided a more transparent API interface for manipulating the raw files.imagepipe
rawler
, this is because the original library used std::time
for logging. However, this is unavailable in WebAssembly at runtime. The forked library removes this logging.CFA what is CFA (TODO)
Demosaicing
Big shoutout to these libraries