JavaScript Canvas putImageData 教程
最后修改于 2025 年 4 月 3 日
在本文中,我们将探讨 JavaScript 中的 Canvas putImageData 方法。此方法对于 HTML canvas 上的直接像素操作至关重要。掌握 putImageData 对于图像处理和特效至关重要。
基本定义
putImageData 是一个 Canvas API 方法,用于将像素数据写入 canvas。它与包含像素颜色值的 ImageData 对象一起工作。这允许对 canvas 像素进行直接的底层操作。
该方法接受一个 ImageData 对象,并将其绘制到指定的坐标。它还可以选择性地接受一个脏矩形来仅复制部分图像数据。这对于性能优化非常强大。
putImageData 的基本用法
此示例演示了如何创建和绘制简单的 ImageData 对象。
<!DOCTYPE html>
<html>
<head>
<title>Basic putImageData</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Create blank ImageData
const imageData = ctx.createImageData(100, 100);
const data = imageData.data;
// Fill with red pixels
for (let i = 0; i < data.length; i += 4) {
data[i] = 255; // R
data[i + 1] = 0; // G
data[i + 2] = 0; // B
data[i + 3] = 255; // A
}
ctx.putImageData(imageData, 50, 50);
</script>
</body>
</html>
在这个基本示例中,我们创建了一个 100x100 像素的 ImageData 对象。然后,我们通过在 data 数组中设置 RGBA 值将其填充为纯红色像素。
putImageData 方法将此像素数据绘制在位置 (50,50)。这演示了在 canvas 上创建和绘制像素数据的最简单方法。
复制 Canvas 数据
此示例展示了如何复制 canvas 的一部分并对其进行操作。
<!DOCTYPE html>
<html>
<head>
<title>Copy Canvas Data</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw original content
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100);
// Get image data
const imageData = ctx.getImageData(50, 50, 100, 100);
const data = imageData.data;
// Invert colors
for (let i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // R
data[i + 1] = 255 - data[i + 1]; // G
data[i + 2] = 255 - data[i + 2]; // B
}
// Draw modified data
ctx.putImageData(imageData, 150, 50);
</script>
</body>
</html>
这里我们首先绘制一个蓝色矩形。然后我们使用 getImageData 复制其像素数据。我们通过反转颜色来修改数据。
修改后的数据使用 putImageData 绘制回 canvas 的新位置。这展示了如何处理现有的 canvas 内容。
部分图像更新
此示例演示了仅使用 putImageData 更新 canvas 的一部分。
<!DOCTYPE html>
<html>
<head>
<title>Partial Update</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Create full canvas image data
const imageData = ctx.createImageData(canvas.width, canvas.height);
const data = imageData.data;
// Fill with gradient
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const i = (y * canvas.width + x) * 4;
data[i] = x % 255; // R
data[i + 1] = y % 255; // G
data[i + 2] = 128; // B
data[i + 3] = 255; // A
}
}
// Draw only a portion (dirty rectangle)
ctx.putImageData(imageData, 0, 0, 50, 50, 100, 100);
</script>
</body>
</html>
此示例创建了一个全 canvas 渐变,但仅绘制了 100x100 的部分。最后四个参数定义了脏矩形(源 x、y、宽度、高度)。
当您只需要更新 canvas 的一部分时,此技术对于性能很有用。绘制过程中会忽略其余像素数据。
图像处理滤镜
此示例展示了如何使用 putImageData 创建简单的灰度滤镜。
<!DOCTYPE html>
<html>
<head>
<title>Grayscale Filter</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<img id="source" src="image.jpg" style="display:none">
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const img = document.getElementById('source');
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// Convert to grayscale
for (let i = 0; i < data.length; i += 4) {
const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
data[i] = avg; // R
data[i + 1] = avg; // G
data[i + 2] = avg; // B
}
ctx.putImageData(imageData, 0, 0);
};
</script>
</body>
</html>
此示例加载图像,将其绘制到 canvas,然后将其转换为灰度。灰度转换会平均每个像素的 RGB 值。
处理后,我们使用 putImageData 将修改后的像素绘制回 canvas。这演示了 putImageData 的实际图像处理。
像素动画效果
此示例使用 putImageData 创建了像素动画效果。
<!DOCTYPE html>
<html>
<head>
<title>Pixel Animation</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Initial drawing
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, canvas.width, canvas.height);
let offset = 0;
function animate() {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
// Shift pixels horizontally
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const i = (y * canvas.width + x) * 4;
const ni = (y * canvas.width + ((x + offset) % canvas.width)) * 4;
data[i] = imageData.data[ni]; // R
data[i + 1] = imageData.data[ni + 1]; // G
data[i + 2] = imageData.data[ni + 2]; // B
}
}
ctx.putImageData(imageData, 0, 0);
offset++;
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
此示例创建了一个水平像素移动动画。每一帧,像素会向右移动一个位置,从而产生滚动效果。
动画循环使用 getImageData 和 putImageData 来不断更新 canvas。这表明 putImageData 可用于实时效果。
来源
在本文中,我们探索了使用 putImageData 操作 canvas 像素的各种技术。掌握此方法对于 Web 应用程序中的高级图形和图像处理至关重要。
作者
列出 所有 JS Canvas 教程。