ZetCode

JavaScript Canvas createImageData 教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas createImageData 方法。此方法对于在 HTML canvas 上进行直接像素操作至关重要。掌握像素操作对于图像处理和特效至关重要。

基本定义

createImageData 使用指定的尺寸创建一个新的空白 ImageData 对象。ImageData 代表 canvas 区域的底层像素数据。它包含宽度、高度和 RGBA 值的数据数组。

数据数组按 RGBA 顺序(红、绿、蓝、Alpha)存储像素值。每个分量的值范围从 0 到 255。Alpha 控制透明度(0=透明,255=不透明)。

创建空白 ImageData

此示例演示了如何创建空白 ImageData 对象并显示它。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic createImageData</title>
</head>
<body>

<canvas id="myCanvas" width="200" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Create 100x100 ImageData object
    const imageData = ctx.createImageData(100, 100);
    
    // Put the ImageData at (50,50)
    ctx.putImageData(imageData, 50, 50);
</script>

</body>
</html>

此示例创建一个 100x100 像素的 ImageData 对象。默认情况下,所有像素都是透明黑色 (RGBA 0,0,0,0)。然后我们将其在 (50,50) 的位置绘制到 canvas 上。

putImageData 方法将像素数据渲染到 canvas 上。这演示了创建和显示 ImageData 的基本工作流程。

操作像素数据

此示例展示了如何修改 ImageData 对象中的像素值。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Pixel Manipulation</title>
</head>
<body>

<canvas id="myCanvas" width="200" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const imageData = ctx.createImageData(100, 100);
    const data = imageData.data;
    
    // Set all pixels to semi-transparent red
    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] = 128; // A (50% opacity)
    }
    
    ctx.putImageData(imageData, 50, 50);
</script>

</body>
</html>

这里我们创建一个 100x100 的 ImageData 并将所有像素修改为半透明红色。数据数组以 RGBA 四联体形式访问和修改。

每个像素占用 4 个连续的数组元素(R、G、B、A)。循环以 4 为步长递增以处理每个像素。Alpha 值 128 使颜色不透明度为 50%。

创建渐变效果

此示例通过操作像素数据创建平滑的颜色渐变。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Gradient Effect</title>
</head>
<body>

<canvas id="myCanvas" width="256" height="256"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const imageData = ctx.createImageData(256, 256);
    const data = imageData.data;
    
    for (let y = 0; y < 256; y++) {
        for (let x = 0; x < 256; x++) {
            const index = (y * 256 + x) * 4;
            data[index] = x;         // R increases horizontally
            data[index + 1] = y;    // G increases vertically
            data[index + 2] = 128;  // Constant blue
            data[index + 3] = 255;   // Fully opaque
        }
    }
    
    ctx.putImageData(imageData, 0, 0);
</script>

</body>
</html>

这创建了一个 256x256 的渐变,其中红色从左到右增加,绿色从上到下增加。蓝色常量为 128(中等强度)。

嵌套循环计算每个像素的位置。索引公式将 2D 坐标转换为 1D 数据数组。这展示了复杂的像素数学。

从现有数据创建 ImageData

此示例展示了如何从现有的 Uint8ClampedArray 创建 ImageData。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>ImageData from Array</title>
</head>
<body>

<canvas id="myCanvas" width="100" height="100"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    // Create array with 100x100 pixels (40000 elements)
    const pixelArray = new Uint8ClampedArray(100 * 100 * 4);
    
    // Make a diagonal red line
    for (let y = 0; y < 100; y++) {
        const x = y;
        const index = (y * 100 + x) * 4;
        pixelArray[index] = 255;     // R
        pixelArray[index + 3] = 255; // A
    }
    
    // Create ImageData from array
    const imageData = new ImageData(pixelArray, 100);
    ctx.putImageData(imageData, 0, 0);
</script>

</body>
</html>

在这里,我们首先创建一个 Uint8ClampedArray 并用像素数据填充它。然后我们从此数组创建 ImageData 对象,指定宽度。

该示例通过为 x 等于 y 的像素设置红色和 Alpha 值来绘制一条红色对角线。其他像素保持透明(默认为 0 值)。

图像处理:反转颜色

此示例演示了通过反转颜色进行的简单图像处理。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Invert Colors</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>
<button id="invertBtn">Invert Colors</button>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    const btn = document.getElementById('invertBtn');
    
    // Draw initial image
    ctx.fillStyle = 'blue';
    ctx.fillRect(50, 50, 300, 200);
    ctx.fillStyle = 'yellow';
    ctx.fillRect(100, 100, 200, 100);
    
    btn.addEventListener('click', () => {
        // Get ImageData of entire canvas
        const imageData = ctx.getImageData(0, 0, 400, 300);
        const data = imageData.data;
        
        // Invert each color channel
        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
            // Alpha remains unchanged
        }
        
        ctx.putImageData(imageData, 0, 0);
    });
</script>

</body>
</html>

此示例首先绘制一个简单的组合,然后提供一个按钮来反转其颜色。反转是通过将每个 RGB 值减去 255 来完成的。

getImageData 捕获当前的 canvas 内容。处理后,putImageData 渲染修改后的像素。这展示了使用 ImageData 进行的实际图像处理。

来源

MDN createImageData 文档

在本文中,我们探讨了创建和操作 ImageData 对象的各种技术。这些方法对于 Web 应用程序中的高级 canvas 操作和图像处理至关重要。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 JS Canvas 教程