JS(react)图片压缩+图片上传

上传dome

                     var fileNodeTakeStock: any = createRef();
                     
                      <input
                        ref={fileNodeTakeStock}
                        onChange={showPictureTakeStock}
                        style={{ display: "none" }}
                        id="fileInpBtn"
                        type="file"
                        accept="image/*"  //限制上传格式
                        multiple={false}
                        capture="environment" //ios有效调用后置摄像头,use后置
                      />
                      <div
                        className={style.upImg}
                        onClick={() => onOpenFileChooserTakeStock()}
                      >
                        点击上传
                      </div>

上传文件

  /** 触发上传 */
  const onOpenFileChooserTakeStock = () => {
    if (!!fileNodeTakeStock) fileNodeTakeStock.current.click();
  };

  /**上传图片*/
  const showPictureTakeStock = (e: any) => {
    getImg(e.target, 0.7).then(({ data, file }) => {
      const formData = new FormData();
      let data2 = dataURLtoFile(data);
      let fileFormat = convertBlobToFile(data2);

      console.log("文件大小", (file as any).size, fileFormat.size,
      'base64大小',getImgSize(data));

      //如果原图小于压缩后的就长传压缩图
      if (fileFormat.size < (file as any).size) {
        formData.append("file", fileFormat);
      } else {
        formData.append("file", file);
      }

      uploadImgFile(formData)
        .then((res) => {
          if (res?.statusCode === NetState.Ok) {
            const newRecord = {
              name: res.data.FrName,
              filePath: res.data.FrPath,
            };

            setImgList((e) => [...e, newRecord]);
          } else {
            return Promise.reject(res?.message || "上传失败\n网络出错");
          }
        })
        .catch((error) => {
          Toast.show(error?.message || "上传失败\n网络出错");
        });
    });
  };
  
  /**base64字符串转为blob对象 */
  const dataURLtoFile = (base64: any) => {
    let binary = atob(base64.split(",")[1]);
    let array = [];
    for (let i = 0; i < binary.length; i++) {
      array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {
      type: "image/png",
    });
  };
  
  /**blob对象转为file对象 */
  const convertBlobToFile = (blob: any) => {
    // 创建File对象
    const file = new File([blob], "test.jpg", { type: blob.type });
    return file;
  };

  // base64图片大小
  const getImgSize = (base64url: any) => {
    //获取base64图片大小,
    var str = base64url.replace("data:image/jpeg;base64,", ""); //这里根据自己上传图片的格式进行相应修改
    var strLength: any = str.length;
    // base64编码方式,计算
    // 计算后得到的文件流大小,单位为字节
    //理解一下base64的编码方式,是把3个8字节编码成4个6字节,到这一步字节数是不变的
    //但它还要在6个字节添加两个高位组成4个8字节,base64有多少个8字节,就比原来多2倍的多少个8字节,
    //也就是base64长度要比原码长度多了(base64长度/8)*2个字节,换算过来就是要减掉
    var fileLength = parseInt((strLength - (strLength / 8) * 2).toString());
    // 由字节转换为Kb
    var size = "";
    size = (fileLength / 1024).toFixed(2);
    return parseInt(size);
  };

压缩图片

getImg(imgFile,quality=0.92) {
  return new Promise((resolve) => {
    const file = imgFile.files[0];
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function (e) {
      const image = new Image(); // 新建一个img标签(还没嵌入DOM节点)
      image.src = e.target.result;
      image.onload = function () {
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        const imageWidth = image.width / 2;
        const imageHeight = image.height / 2;
        canvas.width = imageWidth;
        canvas.height = imageHeight;
        context.drawImage(image, 0, 0, imageWidth, imageHeight);
        //'image/jpeg':图片格式,默认为 image/png,可以是其他image/jpeg等
        //quality:0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值
        const data = canvas.toDataURL('image/jpeg',quality);
        //data-压缩后base64,后面转blob对象, file-源文件
        resolve({ data, file });
      };
    };
  });
}

JS(react)图片压缩+图片上传_第1张图片

你可能感兴趣的:(React,JavaScript,javascript,react.js,前端)