📜  画布绘制图像调整大小质量 - Javascript (1)

📅  最后修改于: 2023-12-03 15:27:15.457000             🧑  作者: Mango

用Javascript绘制和调整画布图像大小和质量

在Javascript中,我们可以使用画布(Canvas)元素来完成图像绘制和调整。本篇文章将介绍如何使用画布绘制图像并调整图像大小和质量。

绘制图像

首先,我们需要在HTML DOM中添加一个画布元素,并且使用Canvas API中的getContext()方法来获取一个绘图环境。绘图环境有两种:2D和WebGL。在这里我们只需要使用2D绘图环境。

<canvas id="myCanvas"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
</script>

接下来,我们可以使用drawImage()方法来绘制一张图片:

const img = new Image();
img.onload = () => {
  ctx.drawImage(img, x, y);
};
img.src = 'example.jpg';

这里,我们首先创建了一个Image对象,并且在图片加载完成后调用了onload回调函数,进而使用drawImage()方法将图片绘制到画布上。

drawImage()方法的参数非常丰富,除了第一个img参数指定绘制的图片对象外,还有其他参数可以控制图像的位置、大小和剪切。详情可以参考MDN文档:CanvasRenderingContext2D.drawImage()

调整图像大小

有时候我们需要将图像调整为不同的大小,比如缩小或放大。在画布中,可以使用drawImage()方法的第三个和第四个参数来控制绘制图像的大小。

第三个参数是绘制图像的宽度,第四个参数是绘制图像的高度。如下所示:

const newWidth = 100; // 新的宽度
const newHeight = 100; // 新的高度
ctx.drawImage(img, x, y, newWidth, newHeight);

但是,简单地改变画布上的图像大小,往往会导致图像的质量下降,因为浏览器在调整图像大小时会重新采样图像,从而导致图像模糊或失真。那么,如何避免这种问题呢?

使用CSS来调整图像大小

我们可以使用CSS来调整画布元素的大小,而不是直接在画布上绘制不同大小的图像。当你需要改变画布中图像的大小时,你只需要改变画布元素的CSS样式即可。

canvas {
  width: 100px;
  height: 100px;
}

在改变CSS样式后,我们需要重新绘制图像以适应新的画布大小,但是这不会影响图像的质量。

创建一个缩略图

当用户需要缩放大量图像时,我们需要创建缩略图。缩略图通常比原始图像小得多,所以我们需要将原始图像缩小一定比例。

const thumbnailWidth = 100;
const thumbnailHeight = img.height * thumbnailWidth / img.width; // 保持长宽比
ctx.drawImage(img, 0, 0, thumbnailWidth, thumbnailHeight);

在这里,我们首先计算出缩略图的宽度和高度,然后绘制缩略图。

改善图像质量

当调整图像大小时,我们需要注意图像质量的问题。如前所述,简单地调整图像大小可能会使图像模糊或失真。

创建高质量的缩略图

为了创建高质量的缩略图,我们可以使用两个技巧:减小缩略图的模糊和增加图像的锐度。

减小模糊

为了减小模糊,我们可以使用imageSmoothingEnabled属性来调整图像的平滑度。

ctx.imageSmoothingEnabled = false;
ctx.drawImage(img, 0, 0, thumbnailWidth, thumbnailHeight);

这里,我们将imageSmoothingEnabled属性设置为false,从而禁用图像平滑。

增加锐度

为了增加锐度,我们可以使用卷积滤波器(Convolution Filter)。卷积滤波器可以对图像进行一些数学运算,从而使图像变得更锐利。

function sharpenImage(img, pixels, amount) {
  const weights = [0, -1, 0, -1, 5, -1, 0, -1, 0];
  const side = Math.round(Math.sqrt(weights.length));
  const halfSide = Math.floor(side / 2);
  const src = pixels.data;
  const sw = pixels.width;
  const sh = pixels.height;
  const w = sw;
  const h = sh;
  const dst = ctx.createImageData(w, h);
  const dstData = dst.data;
  const alphaFac = amount / 100;
  for (let y = 0; y < h; y++) {
    for (let x = 0; x < w; x++) {
      const dstOff = (y * w + x) * 4;
      let r = 0, g = 0, b = 0, a = 0;
      for (let cy = 0; cy < side; cy++) {
        for (let cx = 0; cx < side; cx++) {
          const scy = y + cy - halfSide;
          const scx = x + cx - halfSide;
          if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {
            const srcOff = (scy * sw + scx) * 4;
            const wt = weights[cy * side + cx];
            r += src[srcOff] * wt;
            g += src[srcOff + 1] * wt;
            b += src[srcOff + 2] * wt;
            a += src[srcOff + 3];
          }
        }
      }
      dstData[dstOff] = r + 128 * (1 - alphaFac);
      dstData[dstOff + 1] = g + 128 * (1 - alphaFac);
      dstData[dstOff + 2] = b + 128 * (1 - alphaFac);
      dstData[dstOff + 3] = a;
    }
  }
  ctx.putImageData(dst, 0, 0);
}

在这里,我们定义了一个sharpenImage()函数来增加图像的锐度。该函数使用了一个有9个元素的数组作为卷积核,从而对图像进行锐化。它还使用了createImageData()方法来创建一个新的图像数据对象,并使用putImageData()方法将该图像数据对象绘制到画布上。

改变图像格式

最后,我们还可以使用toDataURL()方法来将图像转换为不同的格式,比如JPEG、PNG和WEBP等格式。

const newImgData = canvas.toDataURL('image/jpeg', quality);

在这里,我们调用了toDataURL()方法并指定了输出的格式和质量。对于JPEG格式,质量的范围是0-1,对于PNG格式,质量的范围是0-10。输出的数据是一个Base64编码的字符串,我们可以将其保存为文件或者传输到服务器端。

总结

在这篇文章中,我们介绍了使用Javascript在画布上绘制图像的方法,并且学习了如何调整图像大小和质量。通过使用CSS调整画布大小和使用卷积滤波器增加图像锐度,我们可以避免图像模糊和失真的问题。最后,我们还可以将图像转换为不同的格式,以便于保存或传输。