为了账号安全,请及时绑定邮箱和手机立即绑定

React Image-crop 显示错误,因为它没有以正确的形式上传图像,并且从后端收到错误

React Image-crop 显示错误,因为它没有以正确的形式上传图像,并且从后端收到错误

qq_花开花谢_0 2023-07-14 10:25:21
我在使用 上传裁剪后的图像时遇到错误react-image-crop。我想,我在上传之前没有正确地将 base64 转换为文件类型,或者该函数没有运行?我对 React 和 javascript 很陌生,很多事情仍然让我感到困惑。任何人都可以看一下代码并帮助解决问题吗?我正在使用 django 休息 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."]这是代码。
查看完整描述

1 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超2个赞

这段代码中不需要使用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>

  );


}


查看完整回答
反对 回复 2023-07-14
  • 1 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信