将带有CSS样式的img复制到画布中以获取最终的dataUrl

时间:2017-07-09 11:18:44

标签: javascript css canvas

假设我的cat.png为800x600像素。

然后我将它放入img并应用CSS对象 - 如下所示:

#cat {
  width: 100px;
  height: 100px;
  object-fit: cover;
}

<img src="cat.png" id="cat">

现在我在屏幕上显示100x100图像。

如何将此最终结果传输到画布中,以便我可以获取dataUrl并以100x100像素保存为cat_thumb.png

这些代码只是忽略了应用于img的CSS:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("cat");
ctx.drawImage(img,0,0,100,100);
console.log(c.toDataURL());

1 个答案:

答案 0 :(得分:1)

看起来需要2个修复:

  • 使用img中的drawImage高度和宽度来使用应用于图像的CSS的高度和宽度。
  • 在创建画布,添加图像并使用img.onload之前,使用toDataURL()等待加载图像。

因为您正在使用object-fit: cover裁剪图像,所以我们还需要对如何在将图像放入画布之前裁剪图像进行一些计算。

这种方法的一个副作用是,当转移到画布时,下采样会产生明显的质量损失。当图像的尺寸调整较小时,这不是问题,并且当将大图像缩小到更小的尺寸时变得更加明显。

我添加了一个非常简单的下采样循环来减少这种影响。简而言之,它会创建一个屏幕外画布,并将其缩小50%,直到图像接近所需大小。

有关此问题的更多信息和可能的解决方案,请参阅many other questions/answers

&#13;
&#13;
var imgEl = document.getElementById("cat");
var img = new Image();
img.crossOrigin = "anonymous";
img.src = imgEl.src;

img.onload = function() {
  // Create an offscreen canvas for downsampling the image
  var oc = document.createElement("canvas");
  var occtx = oc.getContext("2d");

  oc.width = img.width * 0.5;
  oc.height = img.height * 0.5;
  occtx.drawImage(img, 0, 0, oc.width, oc.height);
  
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  var imgRatio = imgEl.width / imgEl.height;
  var sx, sy, sWidth, sHeight;

  if (imgRatio > 1) {
    sx = 0;
    sy = (oc.height / imgRatio) / 2;
    sWidth = oc.width;
    sHeight = oc.height / imgRatio;
  } else if (imgRatio < 1) {
    sx = (oc.width * imgRatio) / 2;
    sy = 0;
    sWidth = oc.width * imgRatio;
    sHeight = oc.height;
  } else {
    sx = 0;
    sy = 0;
    sWidth = oc.width;
    sHeight = oc.height;
  }

  c.width = imgEl.width;
  c.height = imgEl.height;
  ctx.drawImage(oc, sx, sy, sWidth, sHeight, 0, 0, imgEl.width, imgEl.height);
  console.log(c.toDataURL());
}
&#13;
.img-container {
  position: relative;
  margin-top: 0;
}

#cat {
  width: 300px;
  height: 150px;
  object-fit: cover;
}
&#13;
<div class="img-container"><img src="https://i.imgur.com/nZmjnkH.jpg" id="cat" crossOrigin="anonymous"></div>

<canvas id="myCanvas"></canvas>
&#13;
&#13;
&#13;