javascript - 将带有 CSS 样式的 img 复制到 Canvas 中以获得最终的 dataUrl

标签 javascript css canvas

假设我有 800x600 像素的 cat.png

然后我将其放入 img 并应用 CSS object-fit 如下所示:

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

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

现在屏幕上显示了一张 100x100 的图像。

如何将这个最终结果传输到 Canvas 中,以便我可以获得 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());

最佳答案

看起来需要 2 个修复:

  • drawImage 中使用 img 高度和宽度,以使用应用于图像的 CSS 的高度和宽度。
  • 使用img.onload 等待图像加载,然后创建 Canvas 、添加图像并使用toDataURL()

因为您正在使用 object-fit: cover 来裁剪图像,我们还需要在将图像放入 Canvas 之前计算如何裁剪图像。

此方法的一个副作用是,传输到 Canvas 时的下采样会造成明显的质量损失。当图像的大小调整较少时,这不是一个问题,并且在将大图像缩小到更小的尺寸时变得更加明显。

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

有关此问题的更多信息和可能的解决方案可在 many other questions/answers 中找到.

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());
}
.img-container {
  position: relative;
  margin-top: 0;
}

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

<canvas id="myCanvas"></canvas>

关于javascript - 将带有 CSS 样式的 img 复制到 Canvas 中以获得最终的 dataUrl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44995808/

相关文章:

javascript - 按左或右按钮无法更改颜色

javascript - 在javascript中使用arc创建一个圆

javascript - 重构 JSON 对象

html - 模态位置错误

jquery - 使用 className 来定义 Canvas 对象而不是 ID..?

css - 使用与顶级菜单相同颜色的子菜单

jQuery 悬停在一个 div 上

javascript - Bootstrap 折叠导航栏不展开

javascript - 具有远程数据和分页支持的 Qooxdoo 表

javascript - 使用 jQuery 迭代变量不起作用