一、原理:实际上就是利用canvas进行重新绘制

1、先将图片的file文件转成baseURL
2、创建一个image标签去接收文件获取图片的宽高和比例。
3、创建canvas画布设置画布的大小。
4、将图片绘制到canvas上面。
5、对canvas进行压缩处理,获得新的baseURL
6、将baseURL转化回文件。

二、核心代码

/*** 压缩图片* @param file 压缩文件* @param compressThreshold 开启压缩的阈值,默认 5M* @param openCompress 是否开启压缩,默认 true* @param pictureQuality 压缩比,默认 0.92* @returns*/
export const compressFile = (file: File,compressThreshold = 5,openCompress = true,pictureQuality = 0.92
) => {console.log('========== Entry Compress File Function ==========');console.log('before compress file: ', file);//判断是否是图片类型const isAccept = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'].includes(file.type);if (isAccept) {const fileSize = file.size / 1024 / 1024;console.log('before compress, the file size is : ', fileSize.toFixed(2) + ' M');//当开启图片压缩且图片大小大于等于压缩阈值,进行压缩if (fileSize >= compressThreshold && openCompress) {//判断浏览器内核是否支持base64图片压缩if (typeof FileReader === 'undefined') {return file;} else {try {return new Promise(resolve => {//声明FileReader文件读取对象const reader = new FileReader();reader.readAsDataURL(file);reader.onload = () => {// 生成canvas画布const canvas = document.createElement('canvas');// 生成img// const img = document.createElement('img');const img = new Image();img.src = reader.result as any;img.onload = () => {const ctx = canvas.getContext('2d');//原始图片宽度、高度const originImageWidth = img.width,originImageHeight = img.height;//默认最大尺度的尺寸限制在(1920 * 1080)const maxWidth = 1920,maxHeight = 1080,ratio = maxWidth / maxHeight;//目标尺寸let targetWidth = originImageWidth,targetHeight = originImageHeight;//当图片的宽度或者高度大于指定的最大宽度或者最大高度时,进行缩放图片if (originImageWidth > maxWidth || originImageHeight > maxHeight) {//超过最大宽高比例if (originImageWidth / originImageHeight > ratio) {//宽度取最大宽度值maxWidth,缩放高度targetWidth = maxWidth;targetHeight = Math.round(maxWidth * (originImageHeight / originImageWidth));} else {//高度取最大高度值maxHeight,缩放宽度targetHeight = maxHeight;targetWidth = Math.round(maxHeight * (originImageWidth / originImageHeight));}}// canvas对图片进行缩放canvas.width = targetWidth;canvas.height = targetHeight;// 清除画布ctx?.clearRect(0, 0, targetWidth, targetHeight);// 绘制图片ctx?.drawImage(img, 0, 0, targetWidth, targetHeight);// quality值越小,图像越模糊,默认图片质量为0.92const imageDataURL = canvas.toDataURL(file.type || 'image/jpeg', pictureQuality);// 去掉URL的头,并转换为byteconst imageBytes = window.atob(imageDataURL.split(',')[1]);// 处理异常,将ascii码小于0的转换为大于0const arrayBuffer = new ArrayBuffer(imageBytes.length);const uint8Array = new Uint8Array(arrayBuffer);for (let i = 0; i < imageBytes.length; i++) {uint8Array[i] = imageBytes.charCodeAt(i);}const mimeType = imageDataURL?.split(',')?.[0]?.match(/:(.*?);/)?.[1];const newFile = new File([uint8Array], file.name, {type: mimeType || 'image/jpeg'});console.log('after compress, the file size is : ',(newFile.size / 1024 / 1024).toFixed(2) + 'M');console.log('after compress file: ', newFile);resolve(newFile);};};reader.onerror = () => {return file;};}).then(res => {return res;}).catch(() => {return file;});} catch (e) {//压缩出错,直接返回原file对象return file;}}} else {//不需要压缩,直接返回原file对象return file;}} else {//非图片文件,不进行压缩,直接返回原file对象return file;}
};

使用canvas进行图片压缩(前端图片压缩核心处理)相关推荐

  1. 图片纯前端JS压缩的实现

    一.功能体验 先看demo:使用canvas在前端压缩图片并上传demo 如下截图: 点击文件选择框,我们不妨选一张尺寸比较大的图片,例如下面这种2M多的钓鱼收获照: 于是图片歘歘歘地传上去了: 此时 ...

  2. 字体压缩 前端字体压缩

    最近在写官网时候开开心心的将需求开发完成验收完毕,就在上线的时候你发生了奇怪的事情. 上线后通过域名访问发现要很久页面才能展示出来,后来通过排查发现服务器带宽小的可怜,机智的我有通过Network 和 ...

  3. js 压缩html 图片上传,js canvas 前端实现修改图片尺寸压缩图片大小

    函数1:读取图片信息(主要是原使图片宽高) readImg(file) { return new Promise((resolve, reject) => { const img = new I ...

  4. 前端图片压缩上传(纯js的质量压缩,非长宽压缩)

    前端图片压缩上传(纯js的质量压缩,非长宽压缩) 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> ...

  5. 前端实现压缩图片的功能(vue-element)

    前言: 随着现在手机像素,拍照功能越来越好,随之而来的是本地图片越来越大,那么如何更好的将本地图片上传到后端接口呢?这是后台管理系统常见的场景和头疼的问题,这里分享下个人的方法. 实现效果: 如下图所 ...

  6. web 前端图片优化之--图片压缩上传

    移动前端-图片压缩上传实践  此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下.demo效果链接在文章底部贴出. 在做移动端图片上传的时候,用户传 ...

  7. JS前端图片压缩上传

    JS前端图片压缩上传重点知识 最近在做一个手机端的图片上传,写了一个比较符合自己要求的方法,可供参考 在做这个功能模块时,我遇到了以下问题,都花费了大量时间: 1. 不知道怎么压缩图片,(代码和方法) ...

  8. 利用H5Canvas进行前端图片压缩再上传笔记

    前端代码如下: //---------------------压缩图片上传插件--------------------------- var ImgFileGet_class = function(m ...

  9. 前端图片压缩上传(压缩篇)

    为什么说这是一篇比较适合小白的前端图片压缩文章呢?因为我也是一个刚工作半年的前端小白,最近接到了一个前端图片压缩上传的任务,通过各种百度博客完成了这项任务,但是任务完成后对各种技术细节却还不是特别理解 ...

最新文章

  1. 洪小文:以科学的方式赤裸裸地剖析AI(二)|从寒冬到复兴
  2. Web.xml 文件与server.xml 文件使用总结
  3. 大数据架构如何做到流批一体?
  4. windows 7 网卡物理地址修改方法
  5. 多学科可行法matlab,微小卫星多学科建模与仿真方法研究
  6. 实验四 恶意代码技术
  7. 介绍一个能够对日志文件进行自定义高亮的 VS Code 扩展
  8. Python 基础知识整理-2
  9. mybatis plus 新增,修改
  10. 十四、MySQL函数相关知识总结(简单易懂)
  11. javascript设计模式——Publish/Subscribe
  12. SQL进阶六:字符串函数
  13. springboot全局异常处理_SpringMVC全局异常处理
  14. AHP层次分析法具体操作
  15. 热敏电阻 温度 电阻换算
  16. 安装和使用Entrez Direct
  17. 2017网易雷火实习生招聘编程题
  18. unity实现简单游戏——井字棋
  19. 商详压测jjmeter配置
  20. 基于Ant的Mentions自定义公式功能

热门文章

  1. GAN ZOO - 第1节: 分析GAN的缺陷与改进方向,介绍典型的改进模型:CGAN、InfoGAN
  2. 查看Linux的核数和内存等相关系统配置
  3. RDMA RC UC UD
  4. 【互联网寒冬】经历裁员,拿20W被迫去大厂
  5. 使用MATLAB连接USRP实现收发OFDM功能代码说明
  6. 2、JDK,JRE,JVM关系
  7. Ubuntu设为桥接模式自动获取ip但无法上网
  8. Unity3D-Shader之两张图片叠加并且通过颜色调控
  9. python中 range 与 arange 的用法与区别:
  10. 大数据实时计算流程介绍