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

本文介绍了如何使用JavaScript在前端实现文件上传,包括使用`input`元素、`ref`属性处理文件选择,以及对上传图片进行压缩。代码展示了如何将Base64转换为Blob和File对象,以及如何利用Canvas进行图片压缩的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上传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 });
      };
    };
  });
}

在这里插入图片描述

如果您使用React编写前端页面,并且需要上传图片压缩,可以使用以下步骤: 1. 安装用于图片压缩的库,如`compressorjs`或`react-image-file-resizer`。 2. 创建一个组件来上传图片,可以使用`<input type="file">`元素。 3. 当用户选择图片时,可以将其读入内存并压缩。 4. 压缩完毕后,将压缩后的图像作为文件上传。 以下是一个简单的示例代码: ```javascript import React, { useState } from 'react'; import Compressor from 'compressorjs'; const UploadImage = () => { const [file, setFile] = useState(null); const handleFileChange = (event) => { const imageFile = event.target.files[0]; new Compressor(imageFile, { quality: 0.6, success(result) { setFile(result); }, error(err) { console.log(err.message); }, }); }; const handleUpload = () => { // 将压缩后的图像作为文件上传 const formData = new FormData(); formData.append('image', file); // 发送formData到服务器 }; return ( <div> <input type="file" onChange={handleFileChange} /> <button onClick={handleUpload}>上传图片</button> </div> ); }; export default UploadImage; ``` 在这个示例中,我们使用`compressorjs`库来压缩图像。`handleFileChange`函数会在用户选择图片后调用,将图片读入内存并压缩,然后将压缩后的图像设置为组件状态的`file`属性。 `handleUpload`函数在用户点击“上传图片”按钮时调用,将压缩后的图像作为文件上传。您可以将`formData`发送到服务器并在服务器端进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值