canvas压缩图片的秘密

栏目: Html5 · 发布时间: 5年前

内容简介:首先明确canvas只适合压缩大的图片,图片size过小并不能有什么用处。那么为什么size过小canvas并不能压缩呢图片在经过canvas后变大了,口怕。我们对比了两组不同的数据,我们发现原始图片越大,变大的比例越小,如果一张图片越小经过canvas的图片变大的比例也就越大。那么为什么会这样呢图片越小说明本身被压缩的越厉害,其中存在的空白像素点越多,进过drawImage绘制的时候,drawImage才不会去管空白像素,canvas本身绘制的是矢量图所以没有像素的概念,那么经过canvas后空白像素也成

首先明确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<6228026

229kb
229214<242046

60kb
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 = 1

  EXIF.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
  //生成canvas
  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext("2d");
  
  if(Orientation==3||Orientation==6){
    canvas.width = height
    canvas.height = width
  } else{
    canvas.width = width
    canvas.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 = null
  canvasDataURL(file, 0.7, blob => {
    // 处理后的file
    newFile = new File([blob], file.name, { type: blob.type })
    if (!newFile || newFile.size > file.size) {
      newFile = file
    }
    callback(newFile)
  });
}

export default compressionImg;
复制代码

以上所述就是小编给大家介绍的《canvas压缩图片的秘密》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

运营攻略

运营攻略

陈辉 / 人民邮电出版社 / 2017-12 / 59

《运营攻略 移动互联网产品运营提升笔记》深入浅出地告诉大家什么是运营,梳理了移动互联网时代各类运营方向的工作重点与工作方法,结合实例指出了每类运营方向的提升要点;结合作者的亲身经历,解答了无数运营人与产品人纠结的运营与产品到底有什么异同的问题;指明了运营人的核心竞争力,并对处于不同阶段的运营人提出了相应的建议与要求;尤为难得的是,《运营攻略 移动互联网产品运营提升笔记》中还阐述了内容型产品与工具型......一起来看看 《运营攻略》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具