Canvas 05

绘制图片

图像操作能力,可以动态合成图形或者使用图片作为背景图。 引入图片到canvas中:

  • 获取一个HTMLImageElement的元素或者canvas元素。
  • 使用drawImage将图片源绘制到画板上。

支持的哪些类型的图片源

  • HTMLImageElement 可以由Image函数构造或者元素
  • HTMLVideoElement
  • HTMLCanvasElement 元素
  • ImageBitmap 高性能的位图,低延迟绘制
  • SVGImageElement 这些源都可由CanvasImageSource类型引用。

获取图片源的方式

document.images document.getElementsByTagName() document.getElementById() 还可以使用其他已经准备好的canvas。

创建图像元素

使用Image方法创建一个HTMLImageElement对象

var img = new Image(); // 创建一个<img>元素
img.src = "myImage.png"; // 设置图片源地址

我们需要确保图片加载完成之后才调用drawImage,我们可以使用load事件来监听回调执行drawImage方法绘制图片。

var img = new Image(); // 创建 img 元素
img.onload = function () {
  // 执行 drawImage 语句
};
img.src = "myImage.png"; // 设置图片源地址

使用data:url方式嵌入图片

Data urls允许用一串Base64编码的字符串方式定义图片

img.src =
  "data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==";

使用base64图片比较方便,但是没有方法缓存,图片过大数据会过长。

使用视频帧

可以使用video视频元素作为视频帧,获取当前视频第一帧作为图片源。

function getMyVideo() {
  var canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");

    return document.getElementById("myvideo");
  }
}

绘制图片

drawImage(image, x, y)

示例

function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var img = new Image();
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    ctx.beginPath();
    ctx.moveTo(30, 96);
    ctx.lineTo(70, 66);
    ctx.lineTo(103, 76);
    ctx.lineTo(170, 15);
    ctx.stroke();
  };
  img.src = "backdrop.png";
}

缩放

drawIamge方法第二种调用,添加了缩放参数。 drawImage(image, x, y, width, height)

图像缩放会导致图形变得模糊,特别是文字信息会变得无法辨认了。 示例

function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  const img = new Image();
  img.onload = () => {
    for (let i = 0; i < 4; i++) {
      for (let j = 0; j < 3; j++) {
        ctx.drawImage(img, j * 50, i * 38, 50, 38);
      }
    }
  };
  img.src = "https://mdn.github.io/shared-assets/images/examples/rhino.jpg";
}

draw();

切片

drawImage的第三种用法,用于切片和控制切片。 drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 切片主要是用于图像合成。

示例

<canvas id="canvas" width="150" height="150"></canvas>
<div style="display: none;">
  <img
    id="source"
    src="https://mdn.github.io/shared-assets/images/examples/rhino.jpg"
    width="300"
    height="227" />
  <img id="frame" src="canvas_picture_frame.png" width="132" height="150" />
</div>

----
async function draw() {
  // 等待所有图片的加载。
  await Promise.all(
    Array.from(document.images).map(
      (image) =>
        new Promise((resolve) => image.addEventListener("load", resolve)),
    ),
  );

  const canvas = document.getElementById("canvas");
  const ctx = canvas.getContext("2d");

  // 绘制切片
  ctx.drawImage(
    document.getElementById("source"),
    33,
    71,
    104,
    124,
    21,
    20,
    87,
    104,
  );

  // 绘制相框
  ctx.drawImage(document.getElementById("frame"), 0, 0);
}

draw();

控制图像的缩放行为

通过实践我们可以知道缩放图像会导致图像模糊或者像素化,我们可以通过设置imageSmoothingEnabled属性控制缩放图像时使用平滑算法。(默认为true)

写在最后

未完待续… 希望大家好好生活,健康快乐。