React中如何通过react-easy-crop获取裁剪图无需下载直接上传后端
React项目通过react-easy-crop获取裁剪图片并直接提交后端的实现方案
核心逻辑说明
react-easy-crop本身仅会返回裁剪区域的坐标参数,不会直接生成裁剪后的图片。我们只需要在官方提供的canvas转图片逻辑基础上,去掉下载触发逻辑,直接导出图片Blob/File对象即可提交给后端,全程不会触发本地下载。
步骤1:安装依赖
npm install react-easy-crop # 或者yarn yarn add react-easy-crop
步骤2:封装裁剪结果转图片Blob的工具函数
这个函数是核心,输入原始图片地址、裁剪坐标参数,直接返回标准图片格式的Blob对象:
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') // 处理跨域图片问题 image.src = url }) async function getCroppedImg(imageSrc, pixelCrop) { const image = await createImage(imageSrc) const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = pixelCrop.width canvas.height = pixelCrop.height ctx.drawImage( image, pixelCrop.x, pixelCrop.y, pixelCrop.width, pixelCrop.height, 0, 0, pixelCrop.width, pixelCrop.height ) // 把canvas转成jpeg格式的Blob,第二个参数是图片质量0-1,可自行调整 return new Promise((resolve, reject) => { canvas.toBlob( (blob) => { if (!blob) { reject(new Error('Canvas is empty')) return } resolve(blob) }, 'image/jpeg', 0.9 ) }) }
步骤3:组件内使用Cropper并保存裁剪参数
import { useState, useCallback } from 'react' import Cropper from 'react-easy-crop' import axios from 'axios' const ImageCropComponent = () => { const [crop, setCrop] = useState({ x: 0, y: 0 }) const [zoom, setZoom] = useState(1) const [croppedAreaPixels, setCroppedAreaPixels] = useState(null) // 替换成你的原始图片地址 const originalImageSrc = '你的原始图片地址' const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => { setCroppedAreaPixels(croppedAreaPixels) }, []) // 提交裁剪结果的逻辑 const handleSubmit = async () => { if (!croppedAreaPixels) return // 拿到裁剪后的图片Blob const croppedBlob = await getCroppedImg(originalImageSrc, croppedAreaPixels) // 构造FormData提交给后端 const formData = new FormData() // 第三个参数是上传的文件名,可自定义 formData.append('upload_image', croppedBlob, 'cropped_image.jpg') // axios提交示例 await axios.post('你的后端接口地址', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) } return ( <div> <div style={{ position: 'relative', width: '100%', height: 400 }}> <Cropper image={originalImageSrc} crop={crop} zoom={zoom} aspect={4 / 3} // 裁剪比例可自行修改 onCropChange={setCrop} onZoomChange={setZoom} onCropComplete={onCropComplete} /> </div> <button onClick={handleSubmit}>提交裁剪图片</button> </div> ) } export default ImageCropComponent
注意事项
- 如果需要png格式的透明背景图,把
canvas.toBlob的第二个参数改成image/png即可 - 跨域图片需要原始图片资源配置了CORS,否则canvas转Blob会报错
- 全程没有生成下载链接触发点击的逻辑,不会触发本地文件下载
内容的提问来源于stack exchange,提问作者Abbos Rakhmonov
相关产品推荐
相关产品推荐

