How to Add FX to Images before Uploading

Christian Nwamba

Excellent and unique aesthetics make it easy to distinguish on social networking sites, especially in today's image-driven environment.

Your image will be more appealing with effects, and it will undoubtedly enhance your imagination.

An image is a universal language that transcends all barriers. It can communicate effectively with anyone, and it will be even more effective if it has a more pleasing appearance.

This article will show you how to add FX to images before uploading.

The completed project is on Codesandbox.

Prerequisite

The knowledge of JavaScript and React.js is required to follow through with this article. Also, you need to ensure that you have Node.js and npm installed to follow along.

To Verify the node version installed, use the following terminal command:

1node -v && npm -v

The above command should output their respective versions if installed.

Project Setup

To create a new project, use the npx create-react-app <project name> command to scaffold a new project in a directory of your choice.

To install the dependencies, you should use the command below:

1cd <project name>
2npm install lena.js

Once the app is created, and the dependencies are installed, you will see a message with instructions for navigating to your site and running it locally. You can do this with the following command.

1npm start

React.js will start a hot-reloading development environment accessible by default at http://localhost:3000.

Next, update the src/App.js file with the code snippet below.

1import { useEffect, useRef, useState } from "react";
2import "./styles.css";
3
4export default function App() {
5
6return (
7 <div className="App">
8 <h1>How to add FX to images before uploading</h1>
9 <div className="splitdiv" id="leftdiv">
10 <div id="leftdivcard">
11 <h1>Select your favourite FX</h1>
12 </div>
13 </div>
14 <div className="splitdiv" id="rightdiv">
15 </div>
16 </div>
17);
18}

The current user interface doesn’t look aesthetically pleasing, so you need to add some styling with CSS. You can update src/styles.css file with the following content in this GitHub Gist.

After adding the styling, your application should look like the image below.

Adding Effects to Image

This section will render a default image which will be us add an effect in the following section.

Replace your return function with the code snippet below to render a default image.

1//...
2return (
3<div className="App">
4 //...
5<div className="splitdiv" id="rightdiv">
6 <div id="itemdivcard">
7 <img
8 style={{ height: "50%" }}
9 crossOrigin="anonymous"
10 id="original-image"
11 src="https://res.cloudinary.com/olanetsoft/image/upload/v1649599954/uploadedFiles/family-picture.jpg"
12 alt="Original"
13 />
14 </div>
15</div>
16</div>
17);
18}

Your application should look like the image below.

Import the lena.js dependency

1import { useEffect, useRef, useState } from "react";
2import {
3 filterImage,
4 red as lenaRed,
5 blue as lenaBlue,
6 green as lenaGreen,
7 canny as lenaCanny,
8 grayscale as lenaGrayscale,
9 invert as lenaInvert,
10 sepia as lenaSepia,
11 noise as lenaNoise,
12 saturation as lenaSaturation,
13 sobelHorizontal as lenaSobelHorizontal,
14 sobelVertical as lenaSobelVertical,
15 sharpen as lenaSharpen,
16 mirror as lenaMirror
17} from "lena.js";
18
19export default function App() {
20 //...
21}

Declare state variable filter with a red, a variable originalRef using a useRef with a default value of null, and filteredRef with a default null value, respectively.

1//...
2
3export default function App() {
4const originalRef = useRef(null);
5const filteredRef = useRef(null);
6const [filter, setFilter] = useState("red");
7
8return (
9 //...
10);
11}

Add filter to image

This section will show you how to add FX to the default image.

First, Create a Filter object as this will determine the filter color.

1//..
2
3export default function App() {
4//...
5
6const filters = {
7 red: lenaRed,
8 blue: lenaBlue,
9 green: lenaGreen,
10 canny: lenaCanny,
11 grayscale: lenaGrayscale,
12 invert: lenaInvert,
13 sepia: lenaSepia,
14 noise: lenaNoise,
15 saturation: lenaSaturation,
16 sobelHorizontal: lenaSobelHorizontal,
17 sobelVertical: lenaSobelVertical,
18 sharpen: lenaSharpen,
19 mirror: lenaMirror
20};
21
22return (
23 //...
24);
25}

Add a dropdown to change filters and create an OnChange function to track the changes.

1//..
2
3export default function App() {
4//...
5
6const OnChange = (e) => {
7 setFilter(e.target.value);
8};
9
10return (
11 <div className="App">
12 <h1>How to add FX to images before uploading</h1>
13 <div className="splitdiv" id="leftdiv">
14 <div id="leftdivcard">
15 <h1>Select your favourite FX</h1>
16 <select
17 name="membership"
18 id="membership"
19 value={filter}
20 onChange={OnChange}
21 >
22 {Object.keys(filters).map((key) => (
23 <option key={key} value={key}>
24 {key}
25 </option>
26 ))}
27 </select>
28 </div>
29 </div>
30 <div className="splitdiv" id="rightdiv">
31 //...
32 </div>
33 </div>
34);
35}

Next, add a useEffect to track the originalRef onload and render the canvas for the filter.

1//...
2
3export default function App() {
4 //...
5
6useEffect(() => {
7 originalRef.current.onload = () => {
8 filterImage(filteredRef.current, filters[filter], originalRef.current);
9 };
10});
11
12return (
13 <div className="App">
14 //...
15 <div className="splitdiv" id="rightdiv">
16 //...
17 <div id="itemdivcard">
18 {filteredRef && (
19 <canvas id="filtered-image" ref={filteredRef}></canvas>
20 )}
21 </div>
22 </div>
23 </div>
24);
25}

Update the image tag by adding a ref attribute.

1<div className="splitdiv" id="rightdiv">
2 <div id="itemdivcard">
3 <img
4 //...
5 ref={originalRef}
6 />
7 </div>
8 //...
9</div>

You should have something similar to what is shown below.

If you notice, nothing happens when we change FX from the dropdown. We need to find a way to ensure the useEffect hook does not run on the initial render using custom hooks.

To achieve this, add the following code snippet.

1//...
2
3export default function App() {
4 //...
5const didMount = useRef(false);
6 //...
7useEffect(() => {
8 if (didMount.current) {
9 filterImage(filteredRef.current, filters[filter], originalRef.current);
10 } else {
11 didMount.current = true;
12 }
13}, [filter]);
14
15return (
16 <div className="App">
17 //...
18 </div>
19);
20}

Testing the application, you should have everything working as expected, as shown below.

Conclusion

This article explained how to add FX to images before uploading using lena.js.

Reference

Christian Nwamba

Developer Advocate at AWS

A software engineer and developer advocate. I love to research and talk about web technologies and how to delight customers with them.