React+Rust+Wasm: Image Processing

Neo Quest | Nikhil Gupta

Neo Quest | Nikhil Gupta / November 06, 2022

3 min read


In this article, we will alter the redness of an image in our React application from our Rust WASM library using Photon APIs. We will build on the previous tutorial available here.

Add photon-rs to the dependencies

First of all, let's add photon-rs as a dependency:

# Cargo.toml

name = "rust-wasm-lib"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at

crate-type = ["cdylib"]

js-sys = "0.3.60"
wasm-bindgen = "0.2.83"
photon-rs = "0.3.1"

version = "0.3.4"
features = [

Image Processing using Rust

Last time, we exposed a function to render a triangle using WebGL2 2D APIs. Now, let's modify our to expose another function that will take the DOM Id of the canvas element and alter the redness value of its image.

Create a 2D context

pub fn alter_red(element_id: &str) {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");

    let canvas = document
        .expect("no canvas found");
    let canvas: web_sys::HtmlCanvasElement = canvas
        .map_err(|_| ())

    let context = canvas

    # We will fill this piece later

Import Photon-Rs

use photon_rs::*;

Read Image from Canvas

pub fn alter_red(element_id: &str) {

    let mut image = open_image(canvas.clone(), context.clone());

We create a mutable reference so that we could modify the red channel later.

Use Photon-Rs API to alter redness

pub fn alter_red(element_id: &str) {

    channels::alter_red_channel(&mut image, 40);

Draw altered image back on canvas

pub fn alter_red(element_id: &str) {

    putImageData(canvas, context, image);


Build the new wasm library

Let's run wasm-pack again to build the updated library

wasm-pack build --target web

Call the new function from the demo app

Finally, let's import an image, draw it on a canvas and call the exported alter_red function from our App.ts file like so:

// App.ts

import React, { useEffect } from 'react';
import init, { alter_red } from "rust-wasm-lib";
import './App.css';
import test from './test.png';

function App() {
  useEffect(() => {
    init().then(() => {
      const img = new Image();

      img.onload = () => {
        const canvas = (document.getElementById("canvas") as HTMLCanvasElement)!;
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext("2d");

        ctx!.drawImage(img, 0, 0);

      img.src = test;
  }, [])

  return (
    <div className="App">
      <canvas id="canvas" width={400} height={400} />

export default App;

Now, if you run the updated app, you should see an altered image on the screen. :)

Try commenting the alter_red call to see the difference between original and altered image.

If you liked this article, subscribe here to get the complete code and updates for the entire collection: Rust & Wasm