使用画布下载图像会增加文件的大小

时间:2018-02-22 09:08:56

标签: javascript image html5-canvas

当我尝试使用画布操作图像时,没有任何修改,我的图像文件大小比原始文件大得多。

你能解释一下为什么会发生这种情况以及如何避免这种情况吗?

https://jsfiddle.net/95rnh4yj/

function one(selector) {
  return document.querySelector(selector);
}

function on(element, event, listener) {
  element.addEventListener(event, listener);
}

function blobToUrl(blob) {
  return Promise.resolve(URL.createObjectURL(blob));
}

function urlToImg(url) {
  return new Promise(function (resolve) {
    let
    img = new Image();

    img.src = url;

    on(img, 'load', function (event) {
       resolve(event.target);
    });
  });
}

function imgToBlob(img) {
  return new Promise(function (resolve) {
    let
    canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    context.fillStyle = 'transparent';
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.save();
    context.drawImage(img, 0, 0);
    canvas.toBlob(resolve, 'image/jpeg', 1);
  });
}

function writeSrc(src) {
  one('a').href = src;
}

on(one('input'), 'change', function(event) {
  blobToUrl(event.target.files[0])
  .then(urlToImg)
  .then(imgToBlob)
  .then(blobToUrl)
  .then(writeSrc);
})

1 个答案:

答案 0 :(得分:5)

如果问题是文件大小,请更改质量设置。
目前您将其设置为100.将其更改为例如0.95

function imgToBlob(img) {
  return new Promise(function (resolve) {
    let
    canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    context.fillStyle = 'transparent';
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.save();
    context.drawImage(img, 0, 0);
    canvas.toBlob(resolve, 'image/jpeg', 0.95); // <-----
  });
}
  

尝试省略质量设置,看看是否有效:

function imgToBlob(img) {
  return new Promise(function (resolve) {
    let
    canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

    canvas.height = img.naturalHeight;
    canvas.width = img.naturalWidth;
    context.fillStyle = 'transparent';
    context.fillRect(0, 0, canvas.width, canvas.height);
    context.save();
    context.drawImage(img, 0, 0);
    canvas.toBlob(resolve, 'image/jpeg');
  });
}

省略质量设置会为我产生最佳效果(Jsfiddle)。

148kb -> 154kb (jpeg to jpeg)
102kb -> 119Kb