Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • PDF Invoice Generator
Menu

React.js react-easy-crop Example to Crop,Rotate & Zoom Images & Download it as PNG in Browser

Posted on April 6, 2023

 

 

Welcome folks today in this blog post we will be looking at react-easy-crop library to crop,rotate and zoom images and download it as png in browser using javascript. All the full source code of the application is shown below

 

 

 

Get Started

 

 

 

In order to get started you need to make a new react.js project using the below command

 

 

npx create-react-app sampleapp

 

 

cd sampleapp

 

 

And now we need to install the library using the npm command as shown below

 

 

npm i react-easy-crop

 

 

npm i @material-ui/core

 

 

And now you will see the below directory structure of the react.js app as shown below

 

 

 

 

 

And now we need to create the App.jsx file and copy paste the following code

 

 

App.jsx

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React from "react";
import "./App.css";
 
import Cropper from "react-easy-crop";
import Slider from "@material-ui/core/Slider";
import Button from "@material-ui/core/Button";
 
import { generateDownload } from "./utils/cropImage";
 
export default function App() {
const inputRef = React.useRef();
 
const triggerFileSelectPopup = () => inputRef.current.click();
 
const [image, setImage] = React.useState(null);
const [croppedArea, setCroppedArea] = React.useState(null);
const [crop, setCrop] = React.useState({ x: 0, y: 0 });
const [zoom, setZoom] = React.useState(1);
 
const onCropComplete = (croppedAreaPercentage, croppedAreaPixels) => {
setCroppedArea(croppedAreaPixels);
};
 
const onSelectFile = (event) => {
if (event.target.files && event.target.files.length > 0) {
const reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.addEventListener("load", () => {
setImage(reader.result);
});
}
};
 
const onDownload = () => {
generateDownload(image, croppedArea);
};
 
return (
<div className='container'>
<div className='container-cropper'>
{image ? (
<>
<div className='cropper'>
<Cropper
image={image}
crop={crop}
zoom={zoom}
aspect={1}
onCropChange={setCrop}
onZoomChange={setZoom}
onCropComplete={onCropComplete}
/>
</div>
 
<div className='slider'>
<Slider
min={1}
max={3}
step={0.1}
value={zoom}
onChange={(e, zoom) => setZoom(zoom)}
/>
</div>
</>
) : null}
</div>
 
<div className='container-buttons'>
<input
type='file'
accept='image/*'
ref={inputRef}
onChange={onSelectFile}
style={{ display: "none" }}
/>
<Button
variant='contained'
color='primary'
onClick={triggerFileSelectPopup}
style={{ marginRight: "10px" }}
>
Choose
</Button>
<Button variant='contained' color='secondary' onClick={onDownload}>
Download
</Button>
</div>
</div>
);
}

 

 

As you can see we are importing the material-ui library and then we have the two buttons where we allow the user to choose the image file from the laptop or pc and then we are showing the slider to zoom the image or crop the image and we have the download button to download the resultant image.

 

 

And also we need to add the App.css file and copy paste the following code

 

 

App.css

 

 

CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.container {
height: 100vh;
width: 100vw;
}
 
.container-cropper {
height: 90%;
padding: 10px;
}
 
.cropper {
height: 90%;
position: relative;
}
 
.slider {
height: 10%;
display: flex;
align-items: center;
margin: auto;
width: 60%;
}
 
.container-buttons {
border: 1px solid #fffcfc;
height: 10%;
display: flex;
align-items: center;
justify-content: center;
}

 

 

And now we need to define the utils folder and inside it we need to create the cropImage.js file and copy paste the following code

 

 

cropImage.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const createImage = (url) =>
new Promise((resolve, reject) => {
const image = new Image();
image.addEventListener("load", () => resolve(image));
image.addEventListener("error", (error) => reject(error));
image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox
image.src = url;
});
 
function getRadianAngle(degreeValue) {
return (degreeValue * Math.PI) / 180;
}
 
export default async function getCroppedImg(imageSrc, pixelCrop, rotation = 0) {
const image = await createImage(imageSrc);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
 
const maxSize = Math.max(image.width, image.height);
const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2));
 
// set each dimensions to double largest dimension to allow for a safe area for the
// image to rotate in without being clipped by canvas context
canvas.width = safeArea;
canvas.height = safeArea;
 
// translate canvas context to a central location on image to allow rotating around the center.
ctx.translate(safeArea / 2, safeArea / 2);
ctx.rotate(getRadianAngle(rotation));
ctx.translate(-safeArea / 2, -safeArea / 2);
 
// draw rotated image and store data.
ctx.drawImage(
image,
safeArea / 2 - image.width * 0.5,
safeArea / 2 - image.height * 0.5
);
 
const data = ctx.getImageData(0, 0, safeArea, safeArea);
 
// set canvas width to final desired crop size - this will clear existing context
canvas.width = pixelCrop.width;
canvas.height = pixelCrop.height;
 
// paste generated rotate image with correct offsets for x,y crop values.
ctx.putImageData(
data,
0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x,
0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y
);
 
// As Base64 string
// return canvas.toDataURL("image/jpeg");
return canvas;
}
 
export const generateDownload = async (imageSrc, crop) => {
if (!crop || !imageSrc) {
return;
}
 
const canvas = await getCroppedImg(imageSrc, crop);
 
canvas.toBlob(
(blob) => {
const previewUrl = window.URL.createObjectURL(blob);
 
const anchor = document.createElement("a");
anchor.download = "image.jpeg";
anchor.href = URL.createObjectURL(blob);
anchor.click();
 
window.URL.revokeObjectURL(previewUrl);
},
"image/jpeg",
0.66
);
};

 

 

As you can see we are defining all the methods to crop the image with the user selected portion and then we are downloading the cropped portion as an blob png image as shown below

 

 

 

Recent Posts

  • Node.js Express Project to Remove Background of Images Using Rembg & Formidable Library in Browser
  • Node.js Tutorial to Remove Background From Image Using Rembg & Sharp Library in Command Line
  • Python 3 Flask Project to Remove Background of Multiple Images Using Rembg Library in Browser
  • Python 3 Rembg Library Script to Bulk Process Multiple Images and Remove Background in Command Line
  • Python 3 Rembg Library Script to Remove Background From Image in Command Line
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme