react 使用原生input开发拍照上传 && 压缩上传图片大小

本文介绍了如何在React应用中使用原生input实现拍照上传功能,包括创建自定义上传样式、隐藏input、处理文件流、以及针对大图的压缩优化,最后通过FormData发送压缩后的图片到后端。
摘要由CSDN通过智能技术生成

react 使用原生input开发拍照上传功能

实现的思路首先就是创建一个自定义上传的样式,点击自定义上传的时候,通过useRef,获取到input的click事件,这样就可以在onChange里面拿到文件流传递给后端了。

1、创建自定义的上传样式

<div>
 <img
  src={imgSrc}
  onClick={() => inputRef.current.click()}
/>
  <span>点击上传</span>
</div>

2、使用react useRef()获取到input 

const inputRef = useRef();

3.默认将input 进行隐藏(不隐藏会有input上传的原声样式,你也可以直接使用input原生修改样式,就省略了我的第一步和第二步) 

                 <input
                  style={{ display: "none" }}
                  ref={inputRef}
                  className={styles.filess}
                  type="file"
                  accept="image/*"
                  mutiple="mutiple"
                  capture="camera"
                  onChange={(e) => handleUpload(e)}
                />

4.上传图片后获取到的值是文件流形式的参数,到这一步可以进行简单的拍照上传了,如果你发现拍照上传的图片比较大,时间比较长,用户体验上不是很好。可以继续往下看

const handleUpload = async (e) => {
    console.log(e.nativeEvent.srcElement.files[0],"文件流形式");
 
  };

5.拍照后图片过大的优化,

  //压缩文件
  function compressImg(file, quality) {
    var qualitys = 0.52;
    if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
      qualitys = 0.85;
    }
    if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
      qualitys = 0.92;
    }
    if (quality) {
      qualitys = quality;
    }
    if (file[0]) {
        // 如果是 file 数组返回 Promise 数组
      return Promise.all(Array.from(file).map((e) => compressImg(e, qualitys))); 
    } else {
      return new Promise((resolve) => {
        if ((file.size / 1024).toFixed(2) < 300) {
          resolve({
            file: file,
          });
        } else {
          const reader = new FileReader(); // 创建 FileReader
          reader.onload = ({ target: { result: src } }) => {
            const image = new Image(); // 创建 img 元素
            image.onload = async () => {
              const canvas = document.createElement("canvas"); // 创建 canvas 元素
              const context = canvas.getContext("2d");
              var targetWidth = image.width;
              var targetHeight = image.height;
              var originWidth = image.width;
              var originHeight = image.height;
              if (
                1 * 1024 <= parseInt((file.size / 1024).toFixed(2)) &&
                parseInt((file.size / 1024).toFixed(2)) <= 10 * 1024
              ) {
                var maxWidth = 1600;
                var maxHeight = 1600;
                targetWidth = originWidth;
                targetHeight = originHeight;
                // 图片尺寸超过的限制
                if (originWidth > maxWidth || originHeight > maxHeight) {
                  if (originWidth / originHeight > maxWidth / maxHeight) {
                    // 更宽,按照宽度限定尺寸
                    targetWidth = maxWidth;
                    targetHeight = Math.round(
                      maxWidth * (originHeight / originWidth)
                    );
                  } else {
                    targetHeight = maxHeight;
                    targetWidth = Math.round(
                      maxHeight * (originWidth / originHeight)
                    );
                  }
                }
              }
              if (
                10 * 1024 <= parseInt((file.size / 1024).toFixed(2)) &&
                parseInt((file.size / 1024).toFixed(2)) <= 20 * 1024
              ) {
                maxWidth = 1400;
                maxHeight = 1400;
                targetWidth = originWidth;
                targetHeight = originHeight;
                // 图片尺寸超过的限制
                if (originWidth > maxWidth || originHeight > maxHeight) {
                  if (originWidth / originHeight > maxWidth / maxHeight) {
                    // 更宽,按照宽度限定尺寸
                    targetWidth = maxWidth;
                    targetHeight = Math.round(
                      maxWidth * (originHeight / originWidth)
                    );
                  } else {
                    targetHeight = maxHeight;
                    targetWidth = Math.round(
                      maxHeight * (originWidth / originHeight)
                    );
                  }
                }
              }
              canvas.width = targetWidth;
              canvas.height = targetHeight;
              context.clearRect(0, 0, targetWidth, targetHeight);
              // 绘制 canvas
              context.drawImage(image, 0, 0, targetWidth, targetHeight); 
              const。canvasURL = canvas.toDataURL("image/jpeg", qualitys);
              const buffer = atob(canvasURL.split(",")[1]);
              let length = buffer.length;
              const bufferArray = new Uint8Array(new ArrayBuffer(length));
              while (length--) {
                bufferArray[length] = buffer.charCodeAt(length);
              }
              const miniFile = new File([bufferArray], file.name, {
                type: "image/jpeg",
              });
              resolve({
                file: miniFile,
                origin: file,
                beforeSrc: src,
                afterSrc: canvasURL,
                beforeKB: Number((file.size / 1024).toFixed(2)),
                afterKB: Number((miniFile.size / 1024).toFixed(2)),
              });
            };
            image.src = src;
          };
          reader.readAsDataURL(file);
        }
      });
    }
  }

6、upload上传就可以这么写

  const handleUpload = async (e) => {
    const base64Str = e.nativeEvent.srcElement.files[0];
    compressImg(base64Str).then((res) => {
      console.log(res.file, "res.file");
      var formData = new FormData();
      formData.append("file", res.file);
      setUploadfileLoadding(true);
       //将formData传递给后端就可以了
    });
  };

参考链接:前端图片最优压缩

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您使用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、付费专栏及课程。

余额充值