用react实现FileReader结合canvas在前端实现压缩图片并在线预览

本文介绍了如何利用react、FileReader和canvas在前端实现图片压缩及在线预览。通过canvas的drawImage方法将图片绘制到指定大小的画布上,然后将画布转换为base64格式,实现图片的压缩。内容涵盖了单图和多图的压缩处理。

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

用react实现FileReader结合canvas在前端实现压缩图片并在线预览

图片的压缩主要是采用canvas的drawImage方法将原本大小的画布压缩到指定大小的画布中,再通过toDataURL将画布转化为base64格式信息图像
以下主要实践了,单图和多图的压缩;

import React, {
   
    Component } from 'react';
import './Total.scss'

class Imageouput extends Component {
   
   
    constructor(props) {
   
   
        super(props);
        this.state = {
   
   
            imgSrc: '',
            imgSize:'',
            imgSize1:'',
            imgList:[],
            showimg:false
        }
    }

    addImagesFile() {
   
   
        let that=this;
        let imgFile = document.getElementById('images').files[0];
        let form = new FormData();
        form.append('file', imgFile);

        var imageEle=document.getElementById("images");
        let fileList = imageEle.files;
        var imagSize =  document.getElementById("images").files[0].size;
        this.setState({
   
   
            imgSize:(imagSize/1024/1024).toFixed(2)
        });
        let imageDataReader = new FileReader();
        imageDataReader.readAsDataURL(imgFile);
        imageDataReader.onload = function(){
   
   
            let imgValue=this.result;
            that.setState({
   
   
                imgSrc:imgValue
            });
            if(imagSize>1024*1024*2){
   
   
                var img = new Image();
                img.src = imgValue;
                img.onload = function(){
   
   
                    var these = this;
                    
<think>我们正在讨论前端图片上传过程中的压缩处理。根据引用内容,常见的做法是利用Canvas来重新绘制图片调整质量参数实现压缩。具体步骤:1.用户通过input选择图片文件。2.使用FileReader读取图片文件,得到base64编码的图片数据。3.创建一个Image对象,将base64数据赋值给src,等待图片加载完成。4.图片加载完成后,将其绘制到Canvas上,在绘制过程中可以控制图片的尺寸(按比例缩放)和压缩质量。5.调用CanvastoDataURL方法,指定压缩格式(如'image/jpeg')和质量参数(0~1),得到压缩后的base64数据。6.将base64数据转换为二进制文件(Blob或File),然后通过FormData上传。注意点: -压缩质量参数需要根据实际情况调整,过低会影响图片清晰度。-需要考虑图片的方向问题(如手机拍摄的图片可能有旋转),可以通过EXIF信息来调整方向。 -压缩后的图片尺寸也可以根据需求进行调整,比如限制最大宽度或高度。下面是一个基本的实现示例:</think>### 前端图片上传压缩处理指南 在前端实现图片上传压缩的核心思路是通过Canvas API重绘图片调整质量参数,以下是详细步骤和代码实现: #### 实现原理 1. **读取文件**:用户通过`<input type="file">`选择图片 2. **压缩处理**: - 创建`Image`对象加载原始图片 - 使用`Canvas`重绘图片调整尺寸/质量 - 调用`canvas.toDataURL()`获得压缩后的base64数据 3. **格式转换**:将base64转为`Blob`或`File`对象 4. **上传处理**:通过`FormData`提交压缩后的文件 #### 完整代码实现 ```javascript // 图片压缩函数 function compressImage(file, maxWidth = 800, quality = 0.7) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { const img = new Image(); img.src = e.target.result; img.onload = () => { // 计算缩放比例 const scale = maxWidth / img.width; const height = img.height * scale; // 创建Canvas const canvas = document.createElement('canvas'); canvas.width = maxWidth; canvas.height = height; const ctx = canvas.getContext('2d'); // 绘制压缩图片 ctx.drawImage(img, 0, 0, maxWidth, height); // 获取压缩数据(转为Blob) canvas.toBlob( blob => resolve(new File([blob], file.name, { type: 'image/jpeg' })), 'image/jpeg', quality ); }; }; reader.readAsDataURL(file); }); } // 使用示例 document.getElementById('upload-input').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; try { // 执行压缩(限制宽度800px,质量70%) const compressedFile = await compressImage(file, 800, 0.7); // 上传处理 const formData = new FormData(); formData.append('image', compressedFile); // 发送请求(示例使用fetch) await fetch('/upload-api', { method: 'POST', body: formData }); console.log('上传成功'); } catch (err) { console.error('压缩失败', err); } }); ``` #### 关键优化点 1. **方向修正**:处理手机拍摄的EXIF旋转信息(需引入[exif-js](https://github.com/exif-js/exif-js)) 2. **格式保留**:根据原始类型自动选择`image/jpeg`或`image/png` 3. **渐进式压缩**:通过循环逐步降低质量直到满足大小限制 4. **内存管理**:及时释放`canvas`和`Image`对象资源 #### 注意事项 1. 跨域问题:CDN图片需配置`img.crossOrigin = 'Anonymous'` 2. 质量平衡:质量参数建议0.6-0.8,过低会明显失真 3. 移动端兼容:iOS需注意Canvas尺寸限制(建议<4096px) 4. 性能监控:大图处理可能阻塞UI,建议使用Web Worker > 实际项目中可结合Vue/React封装为可复用组件,具体实现可参考Vant的上传组件设计[^2][^3]。对于网络环境较差的移动端应用,此方法能显著减少70%以上的图片体积[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值