JavaScript Canvas getImageData 教程
最后修改于 2025 年 4 月 3 日
在本篇文章中,我们将探讨 JavaScript 中的 Canvas getImageData 方法。此方法对于画布内容的像素级操作至关重要。掌握 getImageData 对于图像处理和视觉效果至关重要。
基本定义
getImageData 方法返回一个 ImageData 对象,该对象表示画布特定区域的像素数据。这些数据包括所选区域中每个像素的 RGBA 值。该方法接受四个参数。
参数是左上角的 x、y 坐标,以及要捕获的矩形的宽度和高度。返回的 ImageData 对象包含宽度、高度和一个像素数据的 Uint8ClampedArray。
基本 getImageData 用法
此示例演示了如何从画布检索像素数据。
<!DOCTYPE html>
<html>
<head>
<title>Basic getImageData</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw a red rectangle
ctx.fillStyle = 'red';
ctx.fillRect(50, 50, 100, 100);
// Get pixel data
const imageData = ctx.getImageData(50, 50, 100, 100);
console.log(imageData);
</script>
</body>
</html>
在这个基本示例中,我们创建一个画布并绘制一个红色矩形。然后,我们使用 getImageData 捕获该矩形的像素数据。
imageData 对象包含 width、height 和 data 属性。data 属性是一个类型化数组,包含区域中每个像素的 RGBA 值。
读取像素颜色
此示例展示了如何从画布读取特定像素的颜色。
<!DOCTYPE html>
<html>
<head>
<title>Reading Pixel Colors</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<p id="output"></p>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const output = document.getElementById('output');
// Draw a gradient
const gradient = ctx.createLinearGradient(0, 0, 300, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(1, 'blue');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 200);
// Get pixel at position (150, 100)
const pixelData = ctx.getImageData(150, 100, 1, 1).data;
output.textContent = `RGBA: ${pixelData[0]}, ${pixelData[1]}, ${pixelData[2]}, ${pixelData[3]}`;
</script>
</body>
</html>
此示例创建了一个从红色到蓝色的渐变,并显示位置 (150,100) 像素的 RGBA 值。像素数据存储在 Uint8ClampedArray 中。
每个像素由四个连续的数组元素 (R,G,B,A) 表示。颜色值的范围为 0 到 255,透明度 (alpha) 的范围也为 0 到 255。
创建灰度滤镜
此示例演示了如何使用 getImageData 创建灰度滤镜。
<!DOCTYPE html>
<html>
<head>
<title>Grayscale Filter</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<button onclick="applyGrayscale()">Apply Grayscale</button>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw a colorful rectangle
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 200);
ctx.fillStyle = 'green';
ctx.fillRect(100, 0, 100, 200);
ctx.fillStyle = 'blue';
ctx.fillRect(200, 0, 100, 200);
function applyGrayscale() {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
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>
此示例创建了一个具有三个彩色矩形的画布。单击按钮时,applyGrayscale 函数会将图像转换为灰度。
该函数获取所有像素数据,计算每个像素 RGB 值的平均值,并将所有三个颜色通道设置为该平均值。然后将修改后的数据放回画布上。
创建颜色反转滤镜
此示例展示了如何使用 getImageData 创建颜色反转效果。
<!DOCTYPE html>
<html>
<head>
<title>Color Inversion</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="200"></canvas>
<button onclick="invertColors()">Invert Colors</button>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw an image or shape
ctx.fillStyle = 'yellow';
ctx.fillRect(0, 0, 300, 200);
ctx.fillStyle = 'purple';
ctx.beginPath();
ctx.arc(150, 100, 80, 0, Math.PI * 2);
ctx.fill();
function invertColors() {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
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
}
ctx.putImageData(imageData, 0, 0);
}
</script>
</body>
</html>
此示例创建了一个带有黄色背景和紫色圆形的画布。invertColors 函数通过从 255 中减去每个颜色通道来反转颜色。
在反转的图像中,红色变为青色,绿色变为品红色,蓝色变为黄色。在此操作中,alpha 通道保持不变。
边缘检测算法
这个高级示例演示了一个简单的边缘检测算法。
<!DOCTYPE html>
<html>
<head>
<title>Edge Detection</title>
</head>
<body>
<canvas id="sourceCanvas" width="300" height="200"></canvas>
<canvas id="edgeCanvas" width="300" height="200"></canvas>
<button onclick="detectEdges()">Detect Edges</button>
<script>
const sourceCanvas = document.getElementById('sourceCanvas');
const edgeCanvas = document.getElementById('edgeCanvas');
const sourceCtx = sourceCanvas.getContext('2d');
const edgeCtx = edgeCanvas.getContext('2d');
// Draw a sample image on source canvas
sourceCtx.fillStyle = 'white';
sourceCtx.fillRect(0, 0, 300, 200);
sourceCtx.fillStyle = 'black';
sourceCtx.beginPath();
sourceCtx.arc(150, 100, 50, 0, Math.PI * 2);
sourceCtx.fill();
function detectEdges() {
const imageData = sourceCtx.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height);
const data = imageData.data;
const width = imageData.width;
const height = imageData.height;
// Create a new ImageData for edges
const edgeData = edgeCtx.createImageData(width, height);
// Simple edge detection (difference with right and bottom pixels)
for (let y = 0; y < height - 1; y++) {
for (let x = 0; x < width - 1; x++) {
const i = (y * width + x) * 4;
const right = ((y * width) + (x + 1)) * 4;
const bottom = ((y + 1) * width + x) * 4;
// Calculate differences
const diffR = Math.abs(data[i] - data[right]) + Math.abs(data[i] - data[bottom]);
const diffG = Math.abs(data[i + 1] - data[right + 1]) + Math.abs(data[i + 1] - data[bottom + 1]);
const diffB = Math.abs(data[i + 2] - data[right + 2]) + Math.abs(data[i + 2] - data[bottom + 2]);
const edgeValue = (diffR + diffG + diffB) / 3;
const edgeIndex = (y * width + x) * 4;
edgeData.data[edgeIndex] = edgeValue;
edgeData.data[edgeIndex + 1] = edgeValue;
edgeData.data[edgeIndex + 2] = edgeValue;
edgeData.data[edgeIndex + 3] = 255;
}
}
edgeCtx.putImageData(edgeData, 0, 0);
}
</script>
</body>
</html>
此示例实现了一个基本的边缘检测算法。它将每个像素与其右侧和底部的邻居进行比较,以检测颜色差异。
该算法计算所有颜色通道的平均差值。较大的差异表示边缘,这些边缘以灰度值的形式绘制在第二个画布上。这展示了高级像素操作。
来源
在本篇文章中,我们探索了使用 getImageData 操作画布像素的各种技术。这些方法对于在 Web 应用程序中进行图像处理和创建视觉效果至关重要。
作者
列出 所有 JS Canvas 教程。