尝试通过 canvas.toDataURL 压缩 img

Trying to compress img via canvas.toDataURL

我正在尝试 img/canvas 缩放,但它不起作用。

我有一张图片,我想压缩它,所以我使用 canvas 使用以下代码执行此操作:

<img id='srcimg'>
<img id='copyimg'>

function doSendToCanvasThenCopyImg(srcimg, destimg) {
  var scale = 1;
  var natW = srcimg.naturalWidth;
  var natH = srcimg.naturalHeight;
  var newCanvas = document.createElement('canvas');
  newCanvas.width = parseInt(natW * scale);
  newCanvas.height = parseInt(natH * scale);

  var ctx = newCanvas.getContext("2d");
  ctx.drawImage(srcimg, 0, 0, natW, natH, 0, 0, newCanvas.width, newCanvas.height);

  var base64 = newCanvas.toDataURL('image/jpeg', 1);
  destimg.src = base64;
}

function scaleToFit(img, newW, natW, natH) {
  var scale = newW / natW;

  var newCanvas = document.createElement('canvas');
  var ctx = newCanvas.getContext("2d");
  ctx.drawImage(img, 0, 0, natW, natH, 0, 0, parseInt(natW * scale), parseInt(natH * scale));

  var base64 = newCanvas.toDataURL('image/jpeg',1);
  img.src = base64;
}

但这似乎只显示 src 图片的左上角。为什么会这样,我怎样才能得到完整的图像?

其次,我试图测量图像的磁盘空间大小,所以我使用函数:

function getImageSize(img) {
  var can = document.createElement('canvas');
  var natW = img.naturalWidth;
  var natH = img.naturalHeight;
  can.width = natW;
  can.height = natH;
  var ctx = can.getContext("2d");
  ctx.drawImage(img, 0, 0, natW, natH, 0, 0, natW, natH);
  var base64 = can.toDataURL('image/jpeg',1);
  return base64.length;
}

但这似乎导致了不正确的结果 - 复制后 img [base64] src 是空白的 - 谁能帮忙?

我在 https://jsfiddle.net/Abeeee/9bzk7h6w/ 上找到了一个 运行 示例(抱歉 - 它包含一个非常大的 base64 图像,因为我找不到在 jsfiddle 中包含图像的方法,外部图像会导致安全问题脚本问题)。

  1. 当 运行 示例并单击 [运行 步骤 1] 时,我看到了预期的结果图像,但指示的图像尺寸有误。
  2. 当 运行 示例并单击 [运行 步骤 1 和 2] 时,我只看到部分结果。

回顾一下 - 我正在尝试调整 JavaScript 中的图像大小,并希望在执行过程中查看生成的文件大小。

怎么回事?

好的,看起来部分结果图像是由两个问题引起的 - a) newCanvas 需要设置 .width 和 .height,

function doSendToCanvasThenCopyImg(srcimg, destimg) {
  var scale = 1;
  var natW = srcimg.naturalWidth;
  var natH = srcimg.naturalHeight;
  var newCanvas = document.createElement('canvas');
  newCanvas.width = parseInt(natW * scale);            <----------
  newCanvas.height = parseInt(natH * scale);           <----------

  var ctx = newCanvas.getContext("2d");
  ctx.drawImage(srcimg, 0, 0, natW, natH, 0, 0, newCanvas.width, newCanvas.height);

  var base64 = newCanvas.toDataURL('image/jpeg', 1);
  destimg.src = base64;

b) doSendToCanvasThenCopyImg 的调用似乎需要等待 copyimg 被加载后才能被处理

  var done=false; // bit quick and nasty but prevents the scaleToFit from recursively triggering onload
  copyimg.onload = function() {
    if ( !done ) {
      done=true;
      var destW = 500;
      scaleToFit(copyimg, destW, srcimg.naturalWidth, srcimg.naturalHeight);
    }
  }