开篇

首先明确canvas只适合压缩大的图片,图片size过小并不能有什么用处。那么为什么size过小canvas并不能压缩呢

  • 如果不压缩质量,经过canvas的图片变大了
  • 图片在经过img标签的时候方向改变了
  • 什么时候使用canvas压缩

我们来看看canvas toDataURL toBlob 方法

// 不压缩,原画质
canvas.toBlob(callback, "image/jpeg", {quality: 1});
canvas.toDataURL( "image/jpeg", {quality: 1});
复制代码

图片在经过canvas后变大了,口怕。我们对比了两组不同的数据,我们发现原始图片越大,变大的比例越小,如果一张图片越小经过canvas的图片变大的比例也就越大。那么为什么会这样呢

5.3M
5284528<6228026229kb
229214<24204660kb
60022<229214
复制代码

图片越小说明本身被压缩的越厉害,其中存在的空白像素点越多,进过drawImage绘制的时候,drawImage才不会去管空白像素,canvas本身绘制的是矢量图所以没有像素的概念,那么经过canvas后空白像素也成了真实像素,所以就解释了为什么会出现上面的情况

选择0.7的压缩质量是比较正常的,但是小图片还是并不理想。对于手机拍摄的照片还是可以的。所以有很大的局限性。

那么为什么不能将质量定义的更小呢?那么就回答开篇的问题。

假设一张图片中有1w个空白像素,到了canvas中就成真实像素了,canvas说我们要压缩点1w个像素,那么 现在真实空白像素确实2w个,大小和原来一样,像素比原来低。

好了我们继续压缩,我们压缩3w个空白现在,现在真实空白像素是4w个,大小也小了。想要拿到几十kb的大小像素怎么样自己想想。在canvas中基本都得拿到几百kb的大小质量才能看。

对于手机拍摄的图片在经过img的时候方向改变了怎么办?

手机拍摄的4、5MB的图片在img标签中从竖屏变成了横屏我们该怎么处理?

在canvas压缩中我们肯定要借助img标签去渲染图片,那么经过了img的时候方向改变了,我们就需要在canvas中去rotate画布,然后再开始绘制

我们怎么知道图片是否被旋转了。我们可以借助exif-js去获取Orientation的值,然后再去旋转画布

什么时候才使用压缩呢?

显然如果能压缩对带宽,存储空间和请求速度都有好处,那么根据上面的规律,我们可以讲处理后的file和原始file做对比,选择一个小的上传

送上我的压缩代码

写的不好,各位大佬可以指点指点,让我的代码有所成长

// 图像压缩import EXIF from 'exif-js'// 获取图片信息
function getImageInfo(img, callback) {let Orientation = 1EXIF.getData(img, function () {Orientation = EXIF.getTag(this, 'Orientation');callback(Orientation)});
}// 旋转画布
function rotate(ctx,Orientation){switch(Orientation){case 3://旋转180度ctx.rotate(Math.PI)break;case 6://旋转90度ctx.rotate(Math.PI/2)break;case 8://旋转270度ctx.rotate(Math.PI*1.5)break;}
}// canvas 绘制图片
function drawImage(img, quality, Orientation, callback) {const { width, height } = img//生成canvasvar canvas = document.createElement("canvas");var ctx = canvas.getContext("2d");if(Orientation==3||Orientation==6){canvas.width = heightcanvas.height = width} else{canvas.width = widthcanvas.height = height  }if(Orientation!=1){ctx.translate(canvas.width/2,canvas.width/2);rotate(ctx, Orientation)ctx.translate(-canvas.width/2,-canvas.width/2);}ctx.drawImage(img, 0, 0);// 图像质量if (!(quality && quality <= 1 && quality > 0)) {quality = 0.7}// quality值越小,所绘制出的图像越模糊canvas.toBlob(callback, "image/jpeg", quality);
}// 图片渲染
function canvasDataURL(file, quality = 0.7, callback) {var img = new Image();img.src = window.URL.createObjectURL(file);img.onload = function () {getImageInfo(img, Orientation => {drawImage(img, quality, Orientation, callback)})};
}function compressionImg(file, callback) {let newFile = nullcanvasDataURL(file, 0.7, blob => {// 处理后的filenewFile = new File([blob], file.name, { type: blob.type })if (!newFile || newFile.size > file.size) {newFile = file}callback(newFile)});
}export default compressionImg;
复制代码

canvas压缩图片的秘密相关推荐

  1. android h5 多图上传源码,JS移动端/H5同时选择多张图片上传并使用canvas压缩图片...

    最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴.我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候 ...

  2. JavaScript 使用canvas压缩图片

    压缩思路 JS 的图片压缩,一般是需要用到 Canvas 的绘图能力,通过调整图片的分辨率或者绘图质量来达到图片压缩的效果. 实现过程 (1)获取上传 Input 中的图片对象 File: (2)将图 ...

  3. canvas压缩图片或者进行视频抓拍

    最近在项目中遇到一个需要抓拍正在播放的视频中的图片,就像截图一样进行实时抓拍,并且使用了base64进行上传,要求图片不能大于2M. 先上代码 public captureVideo(id) {//获 ...

  4. 使用html5+的plus调起相机拍照,使用canvas压缩图片,转成base64传到后台

    html代码: <div class="form-com door"><label for="">门头照:</label>& ...

  5. canvas 压缩图片上传

    问题:前端开发过程中难免会将数据提交到后台,但若是提交的数据过大,特别上传图片这类需求,如果不对上传的图片进行压缩处理,就难免会出现请求时间过长的情况,对于用户体验肯定就不是太友好,那么这时候该如何将 ...

  6. 前台图片Canvas压缩上传小结

    需求来源:之前有个提交审核表单的业务,表单中含有大量附件图片,大约有20多张吧,为了省事,采用的同步上传,一次需要上传很多照片,本来单张图片限制为200KB,这样子总图片大小约为5MB左右,想想也可以 ...

  7. 图片上传时用Canvas 压缩和加水印

    用菜鸟教程模拟的 菜鸟对应链接 https://www.runoob.com/try/try-cdnjs.php?filename=tryhtml5_canvas_tut_img <!DOCTY ...

  8. 十分钟教会你原生JS压缩图片,极其精简版

    十分钟教会你原生JS压缩图片,极其精简版 原文链接:https://blog.csdn.net/yasha97/article/details/83629510 (一)实现思路 先通过input标签获 ...

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

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

最新文章

  1. 怎样用matlab打开mw文,C# matlab混合编程 MWArray使用笔记
  2. 数组-在Shell脚本中的基本使用介绍
  3. React Native学习(七)—— FlatList实现横向滑动列表效果
  4. 网络推广——网络推广专员优化网站有秘诀!
  5. 【Android 启动过程】Android 应用启动流程 | Activity 启动流程
  6. 关于C#调用Excel的资源占用问题
  7. jQuery 图片滚动效果
  8. 铁幕(Iron Curtain)
  9. Eureka-搭建eureka服务
  10. docker+selenium web自动化测试环境的部署
  11. Internet Explorer 6 中的 CSS 增强功能
  12. Spring boot 自动配置工作原理
  13. 拼图游戏和它的AI算法
  14. 帆软已知年和第几周,算出7天日期如何写?
  15. 设置模糊阴影_制作带模糊效果的PPT首页
  16. XCTF-攻防世界CTF平台-Web类——19、mfw(.Git源代码泄露、php的assert断言)
  17. 计算机专业 考研VS工作
  18. 我的世界mysql插件_MySQL Inventory Bridge — 跨服背包[1.7-1.15]【Bukkit】
  19. 用邻接表dfs和bfs图
  20. 心靜如水的時候聽音樂

热门文章

  1. lto1: fatal error: bytecode stream generated with LTO version 8.1 instead of the expected 4.0
  2. 【汇正财经】三大指数集体调整,大盘日K线收星
  3. mysql技能特长怎么写_自我介绍性格技能兴趣特长.doc
  4. 圆盘旋转按钮--自定义view
  5. 极限理论总结06:样本矩与样本中心距
  6. 常用的软件测试工具清单,请查收。
  7. 基于WT588F02KD语音芯片在出租车计价器的应用方案设计解析
  8. 【教程】用Python破解WiFi
  9. archlinux什么桌面好_为Arch Linux安装桌面
  10. Latex安装和示例