How to Crop and Resize Image in the Browser

Christian Nwamba

Cropping an image is typically done to remove an unattractive subject or extraneous information, adjust the aspect ratio of an image, or sometimes magnify the main topic and reduce the angle of view.

This article will show you how to crop and resize an image in the browser with React.

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 react-cropper

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.

1#App.js
2
3import React, { useState } from "react";
4import "./styles.css";
5
6export default function App() {
7 return (
8 <div>
9 <div className="splitdiv" id="leftdiv">
10 <h1 className="main-h1">
11 How to Crop and Resize Image in the Browser using CropperJs
12 </h1>
13 <div id="leftdivcard">
14 <input type="file" />
15 <button type="button" id="leftbutton">
16 Use Default Image
17 </button>
18 &nbsp; &nbsp;
19 <button type="button" id="leftbutton">
20 Crop Image
21 </button>
22 </div>
23 </div>
24 <div className="splitdiv" id="rightdiv">
25 <div id="itemdivcard">
26 <h1>Cropped image will apear here!</h1>
27 </div>
28 </div>
29 </div>
30 );
31}

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.

Cropping with React-cropper

This section will import and setup react-cropper, the JavaScript image cropper you installed earlier, into the src/App.js file.

Import the react-cropper dependency

1//...
2
3import Cropper from "react-cropper";
4import "cropperjs/dist/cropper.css";
5
6export default function App() {
7 return (
8 //...
9 );
10}

Declare state variables, image with a default value of an image url, cropData with a default of an empty string, and cropper with a default of null, respectively.

1//...
2
3const defaultSrc ="https://res.cloudinary.com/olanetsoft/image/upload/v1648679302/uploadedFiles/family.jpg";
4
5export default function App() {
6 const [image, setImage] = useState(defaultSrc);
7 const [cropData, setCropData] = useState("");
8 const [cropper, setCropper] = useState(null);
9
10 return (
11 //...
12 );
13}

Render the Cropper Component

Use the react-cropper dependency installed and set the cropper state variable when the cropper dependency is initialized using the following code snippet.

1//...
2
3export default function App() {
4 //...
5
6return (
7 <div>
8 <div className="splitdiv" id="leftdiv">
9 //...
10 <div id="leftdivcard">
11 //...
12 <Cropper
13 className="cropper"
14 zoomTo={0.5}
15 initialAspectRatio={1}
16 src={image}
17 viewMode={1}
18 minCropBoxHeight={10}
19 minCropBoxWidth={10}
20 background={false}
21 responsive={true}
22 autoCropArea={1}
23 checkOrientation={false}
24 onInitialized={(instance) => {
25 setCropper(instance);
26 }}
27 guides={true}
28 />
29 </div>
30 </div>
31 //...
32 </div>
33);
34}

You should have something similar to what is shown below.

Next, you will implement the image crop functionality using the code snippet below.

1//...
2
3export default function App() {
4 //...
5
6const getCropData = () => {
7 if (typeof cropper !== "undefined") {
8 setCropData(cropper.getCroppedCanvas().toDataURL());
9 }
10};
11
12return (
13 <div>
14 <div className="splitdiv" id="leftdiv">
15 //...
16 <div id="leftdivcard">
17 //...
18 <Cropper
19 //...
20 onInitialized={(instance) => {
21 setCropper(instance);
22 }}
23 guides={true}
24 />
25 </div>
26 </div>
27 <div className="splitdiv" id="rightdiv">
28 <div id="itemdivcard">
29 {cropData ? (
30 <img style={{ height: "50%" }} src={cropData} alt="cropped" />
31 ) : (
32 <h1>Cropped image will apear here!</h1>
33 )}
34 </div>
35 </div>
36 </div>
37);
38}

In the code snippet above has,

  • Created a function *getCropData* which validates that the cropper state variable is not undefined, and then set the cropper using *setCropData* to the cropped canvas
  • Passed the *getCropData* to the onClick event of the Crop Image button
  • Validate the cropData is not empty, and then we render the cropped data image as shown below.

Replace Default Image with Uploaded Image

A default image url was passed to the image state variable in the previous step. You can explore the upload image functionality by allowing users to upload their images.

You can achieve this action by using the code snippet below.

1//...
2
3export default function App() {
4 //...
5
6const onChange = (e) => {
7 e.preventDefault();
8 let files;
9 if (e.dataTransfer) {
10 files = e.dataTransfer.files;
11 } else if (e.target) {
12 files = e.target.files;
13 }
14 const reader = new FileReader();
15 reader.onload = () => {
16 setImage(reader.result);
17 };
18 reader.readAsDataURL(files[0]);
19};
20
21return (
22 <div>
23 <div className="splitdiv" id="leftdiv">
24 //...
25 <div id="leftdivcard">
26 <input type="file" onChange={onChange} />
27 //...
28 </div>
29 </div>
30 //...
31 </div>
32);
33}

In the code snippet above, you created a function onChange triggered when the input tag event changed and reads the file uploaded as data URL.

You should have something similar to what is shown below after testing.

Reset to the Default Image

Next, you will implement the Use Default Image button functionality by creating a function that sets the image state variable using the code snippet below.

1//...
2
3export default function App() {
4 //...
5
6const reset = () => {
7 etImage(defaultSrc);
8};
9
10return (
11 <div>
12 <div className="splitdiv" id="leftdiv">
13 //...
14 <div id="leftdivcard">
15 //...
16 <button type="button" id="leftbutton" onClick={reset}>
17 Use Default Image
18 </button>
19 //...
20 </div>
21 </div>
22 //...
23 </div>
24);
25}

After testing your application, you should have something similar to what is shown below.

Conclusion

This article explained how to crop and resize image in the browser

Resources

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.