1 回答
TA贡献1906条经验 获得超3个赞
这段代码中不需要使用useEffect和useCallback 。ReactCrop 为您提供了 onComplete,因此您唯一需要做的就是在那之后开始绘图。
API错误:
在上面的代码中,您将 base64 字符串发送到 api,但正如我们在错误 api 中看到的,文件格式除外。还需要将名称设置为 blob才能识别为文件。
我收集了这些更改,并且此代码应该可以工作:
export default function ProfilePicEdit() {
const [upImg, setUpImg] = useState();
const imgRef = useRef(null);
const canvasRef = useRef(null);
const [crop, setCrop] = useState({ unit: "%", width: 30, aspect: 1 / 1 });
const croppedImage = useRef(null);
const onSelectFile = (e) => {
if (e.target.files && e.target.files.length > 0) {
const reader = new FileReader();
reader.addEventListener("load", () => setUpImg(reader.result));
reader.readAsDataURL(e.target.files[0]);
}
};
const onLoad = (img) => {
imgRef.current = img;
};
const onCropComplete = (crop) => {
makeClientCrop(crop);
};
const makeClientCrop = async (crop) => {
if (imgRef.current && crop.width && crop.height) {
croppedImage.current = await getCroppedImg(
imgRef.current,
crop,
"newFile.jpeg"
);
}
};
const getCroppedImg = (image, crop, fileName) => {
if (!canvasRef.current || !imgRef.current) {
return;
}
const canvas = canvasRef.current;
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
const ctx = canvas.getContext("2d");
canvas.width = crop.width * pixelRatio;
canvas.height = crop.height * pixelRatio;
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
ctx.imageSmoothingQuality = "high";
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;
resolve(blob);
}, "image/jpeg");
});
};
const onSubmit = (e) => {
let formData = new FormData();
formData.append("profile_pic", croppedImage.current,
croppedImage.current.name);
axiosInstance.put('api/profile/update/', formData)
window.location.reload();
};
return (
<div className="imagecropper">
<form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="profile-pic">
<input
accept="image/*"
id="profile-pic"
onChange={onSelectFile}
name="image"
type="file"
/>
<div className="profile_pic__edit_main">
<img
style={{ width: 40, height: 40 }}
src={upImg}
className="profile__pic_edit"
alt=""
/>
</div>
</label>
</div>
<ReactCrop
src={upImg}
onImageLoaded={onLoad}
crop={crop}
onChange={(c) => setCrop(c)}
onComplete={onCropComplete}
/>
<div>
<canvas
ref={canvasRef}
/>
</div>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Update
</Button>
</form>
</div>
);
}
添加回答
举报