Welcome folks today in this blog post we will be using the react-image-crop
library to crop,rotate and scale
images in react.js. 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 by using the below command
npx create-react-app sampleapp
cd sampleapp
npm i react-image-cropper
After that you will see the below directory
structure
Now you need to edit the index.js
file and copy paste the following code
index.js
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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import ReactDOM from "react-dom"; import React, { PureComponent } from "react"; import ReactCrop from "react-image-crop"; import "react-image-crop/dist/ReactCrop.css"; import "./App.css"; class App extends PureComponent { state = { src: null, crop: { unit: "%", x: 0, y: 0, width: 50, height: 50 } }; onSelectFile = e => { if (e.target.files && e.target.files.length > 0) { const reader = new FileReader(); reader.addEventListener("load", () => this.setState({ src: reader.result }) ); reader.readAsDataURL(e.target.files[0]); } }; // If you setState the crop in here you should return false. onImageLoaded = image => { this.imageRef = image; }; onCropComplete = crop => { this.makeClientCrop(crop); }; onCropChange = (crop, percentCrop) => { // You could also use percentCrop: // this.setState({ crop: percentCrop }); this.setState({ crop }); }; async makeClientCrop(crop) { if (this.imageRef && crop.width && crop.height) { const croppedImageUrl = await this.getCroppedImg( this.imageRef, crop, "newFile.jpeg" ); this.setState({ croppedImageUrl }); } } getCroppedImg(image, crop, fileName) { const canvas = document.createElement("canvas"); const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; canvas.width = crop.width; canvas.height = crop.height; const ctx = canvas.getContext("2d"); ctx.drawImage( image, crop.x * scaleX, crop.y * scaleY, crop.width * scaleX, crop.height * scaleY, 0, 0, crop.width, crop.height ); return new Promise((resolve, reject) => { canvas.toBlob(blob => { if (!blob) { //reject(new Error('Canvas is empty')); console.error("Canvas is empty"); return; } blob.name = fileName; window.URL.revokeObjectURL(this.fileUrl); this.fileUrl = window.URL.createObjectURL(blob); resolve(this.fileUrl); }, "image/jpeg"); }); } render() { const { crop, croppedImageUrl, src } = this.state; return ( <div className="App"> <div> <input type="file" accept="image/*" onChange={this.onSelectFile} /> </div> {src && ( <ReactCrop src={src} crop={crop} ruleOfThirds onImageLoaded={this.onImageLoaded} onComplete={this.onCropComplete} onChange={this.onCropChange} /> )} {croppedImageUrl && ( <img alt="Crop" style={{ maxWidth: "100%" }} src={croppedImageUrl} /> )} </div> ); } } ReactDOM.render(<App />, document.getElementById("root")); |
As you can see we have a simple input
field where we allow the user to select the image
file and then we have attached the onChange
event handler it executes every time the image is changed
by the user and inside it we are executing the method where we are initializing the react-image-cropper
library and user can crop
the image and scale it also. And also we are showing the live preview
of the image as it is cropped
and user can download
the image by right clicking it as shown below