在前端 JavaScript 中,实现图片马赛克效果主要有两种方法:使用 Canvas API 和使用 SVG 滤镜。Canvas API 更为常见和灵活,以下提供使用 Canvas API 实现马赛克效果的代码示例和详细解释:
function mosaic(image, tileSize) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = image.width;
const height = image.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(image, 0, 0);
for (let x = 0; x < width; x += tileSize) {
for (let y = 0; y < height; y += tileSize) {
const data = ctx.getImageData(x, y, tileSize, tileSize);
const averageColor = getAverageColor(data);
ctx.fillStyle = `rgb(${averageColor.r}, ${averageColor.g}, ${averageColor.b})`;
ctx.fillRect(x, y, tileSize, tileSize);
}
}
return canvas.toDataURL();
}
function getAverageColor(imageData) {
let r = 0, g = 0, b = 0;
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
r += data[i];
g += data[i + 1];
b += data[i + 2];
}
const count = data.length / 4;
return {
r: Math.floor(r / count),
g: Math.floor(g / count),
b: Math.floor(b / count),
};
}
// 使用示例:
const img = document.getElementById('myImage'); // 获取图片元素
img.onload = function() {
const mosaicDataURL = mosaic(img, 10); // tileSize 控制马赛克块大小
const mosaicImg = document.createElement('img');
mosaicImg.src = mosaicDataURL;
document.body.appendChild(mosaicImg); // 显示马赛克图片
};
代码解释:
-
mosaic(image, tileSize)
函数:- 接收一个图片元素 (
image
) 和马赛克块大小 (tileSize
) 作为参数。 - 创建一个 Canvas 元素和 2D 绘图上下文。
- 将图片绘制到 Canvas 上。
- 使用双重循环遍历图片,每次循环步长为
tileSize
。 getImageData(x, y, tileSize, tileSize)
获取每个马赛克块的像素数据。getAverageColor(data)
计算马赛克块的平均颜色。- 使用平均颜色填充马赛克块
fillRect(x, y, tileSize, tileSize)
。 - 返回马赛克图片的 Data URL。
- 接收一个图片元素 (
-
getAverageColor(imageData)
函数:- 接收
ImageData
对象作为参数。 - 遍历像素数据,累加 R、G、B 值。
- 计算平均 R、G、B 值并返回。
- 接收
-
使用示例:
- 获取图片元素。
- 图片加载完成后,调用
mosaic
函数生成马赛克图片。 - 创建一个新的图片元素,并将
src
设置为马赛克图片的 Data URL。 - 将马赛克图片添加到页面中。
关键点和优化:
tileSize
控制马赛克块大小: 值越大,马赛克块越大,效果越明显。- 性能优化: 对于大型图片,可以考虑使用 Web Workers 在后台线程处理马赛克效果,避免阻塞主线程。
- 其他效果: 可以修改
getAverageColor
函数,实现不同的颜色处理效果,例如取最暗/最亮颜色等。
SVG 滤镜方法 (简单示例):
<svg width="200" height="200">
<filter id="mosaic">
<feFlood flood-color="black" result="solidColor"/>
<feComposite in="SourceGraphic" in2="solidColor" operator="in" result="shape"/>
<feMorphology operator="dilate" radius="5" in="shape"/> <!-- radius 控制马赛克大小 -->
<feComposite in="SourceGraphic" in2="shape" operator="in"
标签:canvas,const,tileSize,js,马赛克,data,图片
From: https://www.cnblogs.com/ai888/p/18585559