- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 react-image-crop
上传裁剪后的图像时出错.我想,我在上传之前没有正确地将 base64 转换为文件类型,或者该功能没有运行?。我是 React 和 javascript 的新手,所以很多事情仍然让我感到困惑。任何人都可以查看代码并帮助解决问题吗?
我正在使用 django rest api。
这是包的链接:
https://github.com/DominicTobias/react-image-crop
这是我在上传时从后端收到的错误。
{profile_pic: ["The submitted data was not a file. Check the encoding type on the form."]}
profile_pic: ["The submitted data was not a file. Check the encoding type on the form."]
这是代码。
function getResizedCanvas(canvas, newWidth, newHeight) {
const tmpCanvas = document.createElement("canvas");
tmpCanvas.width = newWidth;
tmpCanvas.height = newHeight;
const ctx = tmpCanvas.getContext("2d");
ctx.drawImage(
canvas,
0,
0,
canvas.width,
canvas.height,
0,
0,
newWidth,
newHeight
);
return tmpCanvas;
}
export default function ProfilePicEdit() {
const [{user}, dispatch] = useStateValue()
const { register, handleSubmit } = useForm();
const [upImg, setUpImg] = useState();
// const [image, setImage] = useState(null);
const imgRef = useRef(null);
const previewCanvasRef = useRef(null);
const [crop, setCrop] = useState({ unit: "%", width: 30, aspect: 1 / 1 });
const [completedCrop, setCompletedCrop] = useState(null);
const classes = useStyles();
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]);
// setImage(
// {image: e.target.files[0]}
// )
}
};
const onLoad = useCallback((img) => {
imgRef.current = img;
}, []);
useEffect(() => {
if (!completedCrop || !previewCanvasRef.current || !imgRef.current) {
return;
}
const image = imgRef.current;
const canvas = previewCanvasRef.current;
const crop = completedCrop;
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
);
const reader = new FileReader()
canvas.toBlob(blob => {
reader.readAsDataURL(blob)
reader.onloadend = () => {
dataURLtoFile(reader.result, `sample.jpg`)
}
})
const dataURLtoFile = (dataurl, filename) => {
let arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
let croppedImage = new File([u8arr], filename, {type:mime});
setUpImg({upImg: croppedImage })
}
}, [completedCrop]);
const onSubmit = () => {
let formData = new FormData();
// console.log(upImg)
formData.append('profile_pic', upImg);
axiosInstance.put('api/profile/update/', formData)
// window.location.reload();
}
return (
<div className="imagecropper">
<form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}>
<Grid item xs={6}>
<label htmlFor="profile-pic">
<input
accept="image/*"
className={classes.input}
id="profile-pic"
onChange={onSelectFile}
name="image"
type="file"
ref={register}
/> {console.log(upImg)}
<div className="profile_pic__edit_main">
{upImg === undefined ?
<Avatar src={user && user.profile_pic} alt={user && user.username}
className="profile__pic_edit"
/>
: <Avatar src={upImg} className="profile__pic_edit" alt="" />
}
<div className="profile_pic__edit_icon">
<IconButton color="primary" component="span">
<PhotoCamera fontSize="large" />
</IconButton>
</div>
</div>
</label>
</Grid>
<ReactCrop
src={upImg}
onImageLoaded={onLoad}
crop={crop}
onChange={(c) => setCrop(c)}
onComplete={(c) => setCompletedCrop(c)}
/>
{/* <div>
<canvas
ref={previewCanvasRef}
// Rounding is important so the canvas width and height matches/is a multiple for sharpness.
style={{
width: Math.round(completedCrop?.width ?? 0),
height: Math.round(completedCrop?.height ?? 0)
}}
/>
</div> */}
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Update
</Button>
</form>
</div>
);
}
谢谢
最佳答案
没有必要使用 useEffect 和 useCallback 在这段代码中。
ReactCrop 为您提供 onComplete,因此您唯一需要做的就是在那之后开始绘图。
api错误:
在上面的代码中,您正在向 api 发送 base64 字符串,但正如我们在错误 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>
);
}
关于javascript - React Image-crop 显示错误,因为它没有以正确的形式上传图像并且从后端收到错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64713428/
这个问题已经有答案了: How to do case insensitive string comparison? (23 个回答) 已关闭 3 年前。 用户在我的输入栏中写入“足球”,然后执行第 6
啊,不习惯 javascript 中的字符串。 character_id= + id + correct= + correctOrIncorrect 这就是我需要制作成字符串的内容。如果您无法猜测字符
$(function() { var base_price = 0; CalculatePrice(); $(".math1").on('change', function(e) { Calc
我找不到任何文章回答问题:将Spinnaker部署到Spinnaker将管理的同一Kubernetes集群是否安全/正确?我主要是指生产,HA部署。 最佳答案 我认为Spinnaker和Kuberne
我正在使用MSVC在Windows上从源代码(官方源代码发布,而不是从仓库中)构建Qt5(Qt 5.15.0)。 我正在设置环境。变量,依赖项等,然后运行具有1600万个选项的configure,最后
我需要打印一个包含重复单词的数组。我的数组已经可以工作,但我不知道如何正确计算单词数。我已经知道,当我的索引计数器 (i) 为 49 时,并且当 (i) 想要计数到 50 时,我会收到错误,但我不知道
我正在遵循一个指南,该指南允许 Google map 屏幕根据屏幕尺寸禁用滚动。我唯一挣扎的部分是编写一个代码,当我手动调整屏幕大小时动态更改 True/False 值。 这是我按照说明操作的网站,但
我有一个类“FileButton”。它的目的是将文件链接到 JButton,FileButton 继承自 JButton。子类继承自此以使用链接到按钮的文件做有用的事情。 JingleCardButt
我的 friend 数组只返回一个数字而不是所有数字。 ($myfriends = 3) 应该是…… ($myfriends = 3 5 7 8 9 12). 如果我让它进入 while 循环……整个
这个问题在这里已经有了答案: Is there a workaround to make CSS classes with names that start with numbers valid?
我正在制作一个 JavaScript 函数,当调整窗口大小时,它会自动将 div 的大小调整为与窗口相同的宽度/高度。 该功能非常基本,但我注意到在调整窗口大小时出现明显的“绘制”滞后。在 JS fi
此问题的基本视觉效果可在 http://sevenx.de/demo/bootstrap-carousel/inc.carousel/tabbed-slider.html 获得。 - 如果你想看一看。
我明白,如果我想从函数返回一个字符串文字或一个数组,我应该将其声明为静态的,这样当被调用的函数被返回时,内容就不会“消亡”。 但我的问题是,当我在函数内部使用 malloc 分配内存时会怎样? 在下面
在 mySQL 数据库中存储 true/false/1/0 值最合适(读取数据消耗最少)的数据字段是什么? 我以前使用过一个字符长的 tinyint,但我不确定它是否是最佳解决方案? 谢谢! 最佳答案
我想一次读取并处理CSV文件第一行中的条目(例如打印)。我假设使用Unix风格的\n换行符,没有条目长度超过255个字符,并且(现在)在EOF之前有一个换行符。这意味着它是fgets()后跟strto
所以,我们都知道 -1 > 2u == true 的 C/C++ 有符号/无符号比较规则,并且我有一种情况,我想有效地实现“正确”比较。 我的问题是,考虑到人们熟悉的尽可能多的架构,哪种方法更有效。显
**摘要:**文章的标题看似自相矛盾。 本文分享自华为云社区《Java异常处理:如何写出“正确”但被编译器认为有语法错误的程序》,作者: Jerry Wang 。 文章的标题看似自相矛盾,然而我在“正
我有一个数据框,看起来像: dataDemo % mutate_each(funs(ifelse(. == '.', REF, as.character(.))), -POS) # POS REF
有人可以帮助我使用 VBScript 重新格式化/正确格式化带分隔符的文本文件吗? 我有一个文本文件 ^分界如下: AGREE^NAME^ADD1^ADD2^ADD3^ADD4^PCODE^BAL^A
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我是一名优秀的程序员,十分优秀!