i wanna crop image before upload in frontend (react)
Solution 1
You can crop the image just after selecting the image in front end. For cropping the image these 2 module are best.
Integration of these module is also simple.
Solution 2
I've recently blogged about how to do this using react-uploady.
Check out this codesandbox for the full example.
The code uses react-image-crop but its not tied to it in any way, so you can replace it with any other crop solution you desire.
It boils down to:
import React, { useState, useCallback, useRef } from "react";
import ReactCrop from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import Uploady, { withRequestPreSendUpdate } from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";
import UploadPreview from "@rpldy/upload-preview";
import cropImage from "./cropImage";
const ItemPreviewWithCrop = withRequestPreSendUpdate((props) => {
const { url, updateRequest, requestData } = props;
const [crop, setCrop] = useState({ aspect: 4 / 3 });
const onUploadCrop = useCallback(async () => {
if (updateRequest && (crop?.height || crop?.width)) {
requestData.items[0].file = await cropImage(url, requestData.items[0].file, crop);
updateRequest({ items: requestData.items });
}
}, [url, requestData, updateRequest, crop]);
return (
<>
<ReactCrop
src={url}
crop={crop}
onChange={setCrop}
onComplete={setCrop}
/>
<br/>
<button onClick={onUploadCrop}>Upload Cropped</button>
</>
);
});
export default function App() {
const previewMethodsRef = useRef();
return (
<Uploady destination={{ url: "[upload-url]" }} multiple={false}>
<br />
<UploadButton>Select File</UploadButton>
<br />
<UploadPreview
PreviewComponent={ItemPreviewWithCrop}
previewComponentProps={{ previewMethods: previewMethodsRef }}
previewMethodsRef={previewMethodsRef}
/>
</Uploady>
);
}
It will show the selected file in the crop area with fixed 4/3 aspect ratio (just an example).
Related videos on Youtube
Omar Khaled
Updated on May 26, 2022Comments
-
Omar Khaled almost 2 years
this is product form component i wanna crop the image and upload it without backend then upload it to firebase storage
i wanna crop it automatically or manually in constant aspect ratio to fit card or i want crop it in card itself i tried to use react-image-crop but i didn't success it need alot of setup and i don't know how to do itimport React, { useState } from 'react' import Input from '../../components/input/input.component' import Button from '../../components/button/button.component' import {db} from '../../firebase' import './addproduct.styles.scss' import { storage } from 'firebase' import Spinner from '../../components/spinner/spinner.component' const AddProduct = ({catigories}) => { const [name,setName] = useState('') const [price,setPrice] = useState('') const [catigory,setCatigory] = useState('') const [newCatigoryName,setNewCatigoryName] = useState('') const [newCatigoryImg,setNewCatigorImg] = useState(null) const [image,setImage] = useState(null) const [isSending,setIsSending] = useState(false) console.log(image) const handleSubmit = async (event) => { event.preventDefault() if(name && price && image && catigory){ setIsSending(true) if(catigory === 'addNewCatigory' && newCatigoryImg && newCatigoryName){ await storage().ref().child(`catigories/${newCatigoryName}.jpg`).put(newCatigoryImg) const catigoryImgUrl = await storage().ref().child(`catigories/${newCatigoryName}.jpg`).getDownloadURL() await db.collection('catigories').doc(newCatigoryName).set({ name:newCatigoryName, imgUrl:catigoryImgUrl }) const storageId = `${name}-${price}-${catigory}` await storage().ref().child(`products/${storageId}.jpg`).put(image) const productImgUrl = await storage().ref().child(`products/${storageId}.jpg`).getDownloadURL() await db.collection('products').add({ name:name, price: parseInt(price), imgUrl:productImgUrl, catigory:newCatigoryName }) setIsSending(false) }else{ const storageId = `${name}-${price}-${catigory}` await storage().ref().child(`products/${storageId}.jpg`).put(image) const productImgUrl = await storage().ref().child(`products/${storageId}.jpg`).getDownloadURL() await db.collection('products').add({ name:name, price: parseInt(price), imgUrl:productImgUrl, catigory:catigory }) setIsSending(false) } } } if(isSending){ return <Spinner /> } return ( <div className='product'> <form onSubmit={handleSubmit} className="product__form"> <Input placeholder='Enter Product Name' value={name} setValue={setName} width='100%' fontSize='20px' height='40px' borderRadius='20px'type='text' margin /> <Input placeholder='Product Price' value={price} setValue={setPrice} width='100%' fontSize='20px' height='40px' borderRadius='20px'type='number' margin /> <input type="file" onChange={(event) => event.target.files[0] ? setImage(event.target.files[0]) :null}/> <select className='product__form__select' onChange={(event) => setCatigory(event.target.value)}> <option value=''>Catigories</option> {catigories.map(item => <option key={item.name} value={item.name}>{item.name}</option>)} <option value='addNewCatigory'>other</option> </select> {catigory === 'addNewCatigory' ? <div className='product__form__addcatigory'> <Input placeholder='Catigory Name' value={newCatigoryName} setValue={setNewCatigoryName} width='100%' fontSize='20px' height='40px' borderRadius='20px'type='text' margin /> <input type="file" onChange={(event) => event.target.files[0] ? setNewCatigorImg(event.target.files[0]) :null}/> </div> : null } <Button title='add Item' width='100px' height='40px' style={{borderRadius:'20px'}}/> </form> </div> ) } export default AddProduct