Canvas图片压缩

因为图片的选择 - 压缩 - 上传在实际开发中也是对应的场景,因此本文将介绍如何利用Canvas画布来对图片进行压缩的技术,包括实现思路和具体的代码。

实现思路

[ 1 ] 获取源图像数据

在页面中我们使用input标签(file类型)来让用户选择对应的文件上传。为了等比例的对图片进行压缩,需要获取源图片的宽度和高度等数据参数,这里使用了FileReader构造函数(类)。

具体实现的时候,先调用new FileReader()创建一个FileReader的实例对象,然后为input标签注册change事件监听。当用户选择好文件后,需要先检查是否是图片(通过MIMEType类型判断),再通过FileReader实例来调用readAsDataURL(file)方法来读取图片文件的数据信息,以获取源图片文件的宽度和高度信息。

[ 2 ] 计算宽高压缩比数据

因为示例代码中演示的等比例的进行缩放(压缩),因此需要通过得到目标图片的宽度和高度尺寸数据。 这里列出计算部分的核心代码:

var targetWidth,targetHeight;
var imgWidth = img.width, imgHeight = img.height;
var maxWidth = 150, maxHeight = 150;

// 如果图片尺寸超过限制,那么需要重新计算宽高
if (imgWidth > maxWidth || imgHeight > maxHeight) {

  if (imgWidth / imgHeight >= 1) {
    // 如果更宽,那么就按照宽度限定尺寸
    targetWidth = maxWidth;
    targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
  } else {
    // 如果更高,那么就按照高度限定尺寸
    targetHeight = maxHeight;
    targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
  }
}

[ 3 ] 绘制目标图片

当目标图片(压缩后)的宽高都计算完成后,可以通过Canvas上下文的drawImage方法来完成图片的绘制,drawImage方法的第一个参数为需要绘制的图片数据,该图片数据即为用户通过input标签选择的文件内容。当然,在具体实现的时候还需要读取文件的内容,监听加载完毕之后再设置Image数据源。

reader.onload = function(event) {
  //e.target.result是图片的base64地址信息
  img.src = event.target.result;
}

完整代码

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input type="file" id="file">
<div id="info" style="font-size: 13px"></div>
<canvas id="canvas" height="200" width="200"></canvas>
<script>

  //[1] 获取页面中的文件选择标签
  var oInput  = document.querySelector('#file');

  //[2] 创建FileReader对象用于读取文件信息
  var reader = new FileReader();
  var file   = null;  //文件对象

  //[3] 给文件选择标签添加事件监听
  oInput.addEventListener('change', function (event) {

    //001 获取用户选择的文件
    file = event.target.files[0];

    //002 获取文件的MIMEType类型
    var fileType = file.type;

    //003 检查用户选择的文件是否是图片
    if (fileType.indexOf("image") == 0) {

      //004 如果发现文件是图片则读取图片为DataURL
      reader.readAsDataURL(file);
    }
  });

  //[4] 创建Image图像实例
  var img  = new Image();
  var targetWidth,targetHeight;

  //[5] 监听FileReader对象是否处理完毕,设置图像实例的数据源
  reader.onload = function(event) {

    //说明:e.target.result是图片的base64地址信息
    img.src = event.target.result;
  }

    //[6] 监听Image实例加载,压缩图片并生成预览图像
    img.onload = function () {

      setFileInfo();

      //[7]在页面中创建canvas画布对图片进行缩放(压缩)后绘制
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
      ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
    }

    function setFileInfo() {
      // 获取文件的名称
      var fileName = file.name;

      // 获取文件的大小
      var fileSize = (file.size / 1024 / 1024).toFixed(3) + "M";

      // 图片压缩比计算
      var imgWidth = img.width, imgHeight = img.height;
      var maxWidth = 150, maxHeight = 150;

      // 如果图片尺寸超过限制,那么需要重新计算宽高
      if (imgWidth > maxWidth || imgHeight > maxHeight) {

        if (imgWidth / imgHeight >= 1) {
          // 如果更宽,那么就按照宽度限定尺寸
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (imgHeight / imgWidth));
        } else {
          // 如果更高,那么就按照高度限定尺寸
          targetHeight = maxHeight;
          targetWidth = Math.round(maxHeight * (imgWidth / imgHeight));
        }

        //在页面中显示图片信息
        var html = "<div>1.已选择图片" + fileName + ",大小为" + fileSize + "。</div>\n" +
            "<div>2.图片原尺寸是:" + imgWidth + " x " + imgHeight + "</div>\n" +
            "<div>3.图片压缩尺寸:" + maxWidth + " x " + maxHeight + "</div>\n" +
            "<div>4.图片已压缩为:" + targetWidth + " x " + targetHeight +"</div>\n";

        var oDiv = document.getElementById("info");
        oDiv.innerHTML = html;
      }
    };

</script>
</body>
</html>

 

 

 

 
posted @ 2020-11-02 15:51  zien  阅读(257)  评论(0编辑  收藏  举报