📅  最后修改于: 2023-12-03 15:27:15.457000             🧑  作者: Mango
在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样式即可。
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调整画布大小和使用卷积滤波器增加图像锐度,我们可以避免图像模糊和失真的问题。最后,我们还可以将图像转换为不同的格式,以便于保存或传输。