How To Crop An Image

Nowadays, most modern apps and websites are searching for a way to crop an image from raw and dynamic image data.

In this blog, we will explore a popular React-based solution to get cropped images from image data. This library makes it easy to get cropped images by using simple and typical react components.

Prerequisites:

To continue with this blog, we are considering that you have a very good and clear understanding of react js and its components.

Getting Started:

react-easy-crop is a very popular image cropper react js library. react-easy-crop exports a set of primitives that enables us to get the cropped images by rendering things very easily. It works on the browser on the server and on mobile as a react application does.

It comes with a preview image which enables you to render the cropped image in the browser.

Steps to Implementation into React App:

1)Installing react-image-crop library:

To start with react-image-crop we need to add it to our react application.

npm i react-image-crop --save

2)Now, we are creating a component that can be used to take input images.

import React, { useState } from "react";

import ImageModal from "../cropper/ImageModal";

const ImageInput = ({

 name,

 onChange,

 showPreview,

 imageData,

 defaultPic,

}) => {

 const [image, setImage] = useState("");

 const [modalIsOpen, setModalIsOpen] = useState(false);

 const [height, setHeight] = useState(null);

 const [width, setWidth] = useState(null);




 //funcion to handle cropped image file and store it

 const onChangeHandler = file => {

   onChange({

     [name]: {

       data: file[0],

       src: URL.createObjectURL(file[0]),

     },

   });

 };




 //function to handle selected image file

 //check size of image and store it

 const handleFile = e => {

   if (e.target.files.length > 0) {

     const file = e.target.files;

     var url = URL.createObjectURL(file[0]);

     var img = new Image();

     img.src = url;

     img.onload = function () {

       setWidth(this.width);

       setHeight(this.height);

     };

     const maxAllowedSize = 5 * 1024 * 1024;

     if (file[0].size > maxAllowedSize) {

       console.log("max image size");

     } else {

         setImage(file[0]);

         setModalIsOpen(true);

     }

     e.target.value = null;

   }

 };

 let inputElement;




 return (

   <>

     <ImageModal

       modalIsOpen={modalIsOpen}

       closeModal={() => {

         setModalIsOpen(prevState => !prevState);

       }}

       image={image}

       onCropImage={croppedImg => onChangeHandler([croppedImg])}

       ratio={height / width <= 0.5 ? true : false}

     />

     {showPreview && (

       <div>




           <img

             key={imageData}

             src={imageData ? imageData : defaultPic}

             alt="img"

             onError={e => (e.target.src = defaultPic)}

           />

        

       </div>

     )}

     <div onClick={() => inputElement.click()}>Upload</div>

     <input

       ref={input => (inputElement = input)}

       accept="image/*"

       type="file"

       style={{ display: "none" }}

       onChange={handleFile}

     />

   </>

 );

};




export default ImageInput;


So in the above component, we are using the handleFile function to handle input coming from the user and set it as an image.

Also, we are using onChangeHandler function to store file getting from ImageModal as an object with data of an image and src as an image url

3)Creating a component using react-modal to show selected images into modal.

import React from "react";

import Modal from "react-modal";




const customStyles = {

 content: {

   top: "50%",

   left: "50%",

   right: "auto",

   bottom: "auto",

   marginRight: "-50%",

   transform: "translate(-50%, -50%)",

 },

};




 //ImageModal is use to cropped the store image using ImageCropperand 

 //preview cropped image

const ImageModal = ({ modalIsOpen, closeModal, image, onCropImage, ratio }) => {

 return (

   <div>

     <Modal

       isOpen={modalIsOpen}

       onRequestClose={closeModal}

       style={customStyles}

       contentLabel="Example Modal"

     >

       {image && (

         <ImageCropper

           imgName={image.name}

           onCropImage={onCropImage}

           inputImg={URL.createObjectURL(image)}

           closeModal={closeModal}

           ratio={ratio}

         />

       )}

     </Modal>

   </div>

 );

};




export default ImageModal;

In the above step, we are sharing image data to react-modal and ImageCropper. customStyles are used to place modal in center of the screen

4)Creating a main component from which we want to get a cropped image.

import React, { useCallback, useState } from "react";

import Cropper from "react-easy-crop";

import getCroppedImg from "./cropImage";

const ImageCropper = ({

 onCropImage,

 inputImg,

 imgName,

 closeModal,

 ratio,

}) => {

 const [crop, setCrop] = useState({ x: 0, y: 0 });

 const [zoom, setZoom] = useState(1);

 const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);




 const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {

   setCroppedAreaPixels(croppedAreaPixels);

 }, []);




 //these function is used to preview cropped image 

 const showCroppedImage = useCallback(async () => {

   try {

     const croppedImage = await getCroppedImg(inputImg, croppedAreaPixels);

     onCropImage(

       new File([croppedImage], imgName, {

         type: "image/png",

         lastModified: new Date().getTime(),

       })

     );

   } catch (e) {

     console.error(e);

   }

 }, [croppedAreaPixels]);

 return (

   <div>

     <Cropper

       minZoom={0.4}

       image={inputImg}

       crop={crop}

       zoom={zoom}

       aspect={1}

       restrictPosition={false}

       onCropChange={setCrop}

       onCropComplete={onCropComplete}

       onZoomChange={setZoom}

       style={{

         containerStyle: {

           width: 500,

           height: 500,

           position: "relative",

         },

       }}

     />

     <div>

       <button

         onClick={closeModal}

       >Cancel</button>

       <input

         type="range"

         defaultValue={zoom}

         value={zoom}

         max={3.2}

         min={ratio ? 0.4 : 0.6}

         step={0.1}

         onChange={e => setZoom(e.target.value)}

       />

       <button

         onClick={() => {

           showCroppedImage();

           closeModal();

         }}>Save</button>

     </div>

   </div>

 );

};




export default ImageCropper;

In the above step, we are mainly using 3 tags and 1 third-party component. Those 3 tags are,

1. Cancel Button: Which is used to close modal without saving cropped images and also to remove saved image files. 

2. Range Input: Which is used to zoom in and zoom out images in Cropper.

3. Save Button: Which is used to save the cropped image and show the cropped image in the preview image section.

And a third-party component is Cropper from the react-easy-cropper package. We are using these to crop image

Demo:

image input component | Mindbowser

ImageInput Component

 

image modal and cropper | Mindbowser

Image Modal & Image Cropper

 

Code Sand Box | Mindbowser

 

Live Demo

CodeSandBox

 

coma

Conclusion:

As we see, react-easy-crop is a powerful tool for cropping images on the client side no matter what platform you are on.

Github: https://github.com/shubham-gapat/image-cropper

Keep Reading

Keep Reading

Mindbowser is excited to meet healthcare industry leaders and experts from across the globe. Join us from Feb 25th to 28th, 2024, at ViVE 2024 Los Angeles.

Learn More

Let's create something together!