博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端js压缩图片并上传
阅读量:5972 次
发布时间:2019-06-19

本文共 2628 字,大约阅读时间需要 8 分钟。

公司最近有需要压缩上传图片功能,查找了些资料并实现了一把。

主要用到的原生组件:FileReader、Canvas、Blob、FormData

逻辑步骤:

  1. FileReader.readAsDataURL将上传的图片文件转为Base64格式
  2. 将img绘制到canvas上,canvas.toDataURL压缩图片
  3. new Blob将压缩后的Base64转为Blob格式
  4. FormData.append将图片文件数据存入formdata

Code:

this.compressImage(files[0], (file)=>{    console.log(file);    const formData = new FormData();    formData.append('file', file, file.name || '上传图片.jpeg');}, $.noop);//压缩图片compressImage = (file, success, error) => {    // 图片小于1M不压缩    if (file.size < Math.pow(1024, 2)) {        return success(file);    }    const name = file.name; //文件名    const reader = new FileReader();    reader.readAsDataURL(file);    reader.onload = (e) => {        const src = e.target.result;                const img = new Image();        img.src = src;        img.onload = (e) => {            const w = img.width;            const h = img.height;            const quality = 0.8;  // 默认图片质量为0.92            //生成canvas            const canvas = document.createElement('canvas');            const ctx = canvas.getContext('2d');            // 创建属性节点            const anw = document.createAttribute("width");            anw.nodeValue = w;            const anh = document.createAttribute("height");            anh.nodeValue = h;            canvas.setAttributeNode(anw);            canvas.setAttributeNode(anh);            //铺底色 PNG转JPEG时透明区域会变黑色            ctx.fillStyle = "#fff";            ctx.fillRect(0, 0, w, h);            ctx.drawImage(img, 0, 0, w, h);            // quality值越小,所绘制出的图像越模糊            const base64 = canvas.toDataURL('image/jpeg', quality); //图片格式jpeg或webp可以选0-1质量区间            // 返回base64转blob的值            console.log(`原图${(src.length/1024).toFixed(2)}kb`, `新图${(base64.length/1024).toFixed(2)}kb`);            //去掉url的头,并转换为byte            const bytes = window.atob(base64.split(',')[1]);            //处理异常,将ascii码小于0的转换为大于0            const ab = new ArrayBuffer(bytes.length);            const ia = new Uint8Array(ab);            for (let i = 0; i < bytes.length; i++) {                ia[i] = bytes.charCodeAt(i);            }            file = new Blob( [ab] , {type : 'image/jpeg'});            file.name = name;            success(file);        }        img.onerror = (e) => {            error(e);        }    }    reader.onerror = (e) => {        error(e);    }}

遇到的一些坑:

  1. PNG转JPEG时PNG格式的透明区域会变黑色,需要先手动铺底色
  2. toDataURL参数为PNG时不支持传图片质量,所以需要写死image/jpeg或image/webp,具体可以参考toDataURL的api
  3. formData.append第三个参数filename是有浏览器兼容性问题的,如果不传就是filename=blob,后端校验文件名可能过不去
  4. ajax的contentType和processData需要传false,这和本文关系不大直接带过
  5. 网上说的ios中canvas绘制图片大小限制我在iphone6上测试没遇到,可能和机型或系统有关系,如果有可以在下面留言

结语,压缩功能比较适合移动端,毕竟PC端带宽比较好而且不能兼容IE老版本。

转载地址:http://sczox.baihongyu.com/

你可能感兴趣的文章
智能语音机器人市场对手如此多,微服网络如何更胜一筹
查看>>
linux下设置代理
查看>>
outlook自定义邮件提示声音以及设置接收邮件的间隔时间
查看>>
值传递、指针传递、引用传递的区别
查看>>
facebook 分享,遇到的错误
查看>>
svn 部署问题总结
查看>>
我的友情链接
查看>>
一个用了统计CPU 内存 硬盘 使用率的shell脚本
查看>>
如何恢复默认域策略和默认域控制器策略
查看>>
笔记本进水
查看>>
Nginx配置文件nginx.conf (Apache)
查看>>
jquery和JavaScript区别
查看>>
pxe方式安装gentoo
查看>>
Project Management Library项目管理甘特图控件
查看>>
MySQL存储过程详解
查看>>
解决查看框架源码时 class file editor source not found
查看>>
JDBC接口
查看>>
脏读,不可重复读,幻读
查看>>
ssh反向主动连接 及脚本加密
查看>>
Mysql数据库误删除数据恢复成功
查看>>