Img Compressor

by Qi Wan

HTML

<input type="file">
<button>Compress it</button>
<p id="initial"></p>
<p id="compressed"></p>

JavaScript

function imgCompressor(img, type) {
  var canvas = document.createElement("canvas"),
    ctx = canvas.getContext('2d');
  var width = img.width;
  var height = img.height;
  var ratio;
  // 强制压缩图片为屏幕大小先(针对手机端)
  if ((ratio = width / window.innerWidth) > 1) {
    width /= ratio;
    height /= ratio;
  } else ratio = 1;
  canvas.width = width;
  canvas.height = height;
  ctx.fillStyle = "#fff";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(img, 0, 0, width, height);
  // 进行压缩
  var ndata;
  ndata = canvas.toDataURL('image/jpeg', 0.1);

  // 将base64的图片转成二进制对象
  var ndata2 = ndata.split(',')[1];
  ndata2 = ndata2.replace(/\s/g, '');
  var text = atob(ndata2)
  var buffer = new ArrayBuffer(text.length);
  var ubuffer = new Uint8Array(buffer);
  for (var i = 0; i < text.length; i++) {
    ubuffer[i] = text.charCodeAt(i);
  }

  var blob = new Blob([buffer], {
    type: type
  });
  blob.lastModifiedDate = new Date();
  return blob;
}

function sizeConverter(size) {
  var output = size + 'bytes';
  var multiples = ['K', 'M', 'G'];
  var multiple = 0,
    approx = size / 1024;
  for (; approx > 1; approx /= 1024) {
    output = approx.toFixed(3) + multiples[multiple] + '(' + size + 'bytes)';
    multiple++;
  }
  return output;
}

var $btn = document.getElementsByTagName('button')[0],
  $input = document.getElementsByTagName('input')[0],
  $initial = document.getElementById('initial'),
  $compressed = document.getElementById('compressed');

$btn.onclick = function() {
  var file = $input.files[0];
  if (!file.name.match(/.(jpg|jpeg|png|gif)$/i)) {
    alert('请选择图片文件!');
    return;
  }
  initial.textContent = 'initial:' + sizeConverter(file.size);
  var src = window.URL.createObjectURL(file);
  var img = new Image();
  img.src = src;
  img.onload = function() {
    //进行压缩
    var compressed = imgCompressor(img, file.type);
    $compressed.textContent = 'compressed:' + sizeConverter(compressed.size);
  }
}