JavaScript 和 HTML5 Canvas 实现图像绘制与处理的讲解:
一、创建 Canvas 元素和获取绘图上下文
在 HTML 页面中,我们首先创建一个 <canvas> 元素,并为其指定宽度和高度属性:
html
<canvas id="myCanvas" width="800" height="600"></canvas>
然后,在 JavaScript 代码中,通过 document.getElementById 方法获取这个 <canvas> 元素:
javascript
var canvas = document.getElementById('myCanvas');
接下来,使用 getContext 方法获取 2D 绘图上下文,以便进行后续的绘制操作:
javascript
var ctx = canvas.getContext('2d');
二、绘制基本图形
- 矩形
- fillRect(x, y, width, height) 方法用于绘制填充的矩形。其中, x 和 y 是矩形左上角的坐标, width 是矩形的宽度, height 是矩形的高度。
例如:
javascript
ctx.fillStyle ='red';
ctx.fillRect(10, 10, 100, 100);
上述代码将绘制一个左上角坐标为 (10, 10) 、宽度为 100 像素、高度为 100 像素的红色填充矩形。
- strokeRect(x, y, width, height) 方法用于绘制矩形边框。边框的样式由 strokeStyle 和 lineWidth 属性控制。
示例:
javascript
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.strokeRect(150, 10, 100, 100);
这将绘制一个左上角坐标为 (150, 10) 、宽度为 100 像素、高度为 100 像素的蓝色边框矩形,边框宽度为 5 像素。
- 线条
-
beginPath() 方法用于开始一条新的路径。
-
moveTo(x, y) 方法用于设置线条的起始点。
-
lineTo(x, y) 方法用于从起始点到指定点绘制一条直线。
-
stroke() 方法用于实际绘制线条。
例如:
javascript
ctx.beginPath();
ctx.moveTo(20, 200);
ctx.lineTo(200, 20);
ctx.strokeStyle = 'green';
ctx.stroke();
上述代码首先开始一条新路径,将起始点设置为 (20, 200) ,然后绘制一条到 (200, 20) 的直线,并使用绿色绘制线条。
- 圆形
arc(x, y, radius, startAngle, endAngle, anticlockwise) 方法用于绘制圆形或弧形。
其中, x 和 y 是圆心的坐标, radius 是半径, startAngle 和 endAngle 是以弧度表示的起始角度和结束角度, anticlockwise 是一个布尔值,表示绘制方向是逆时针(true)还是顺时针(false)。
示例:
javascript
ctx.beginPath();
ctx.arc(300, 200, 50, 0, 2 * Math.PI);
ctx.fillStyle = 'yellow';
ctx.fill();
这将绘制一个圆心在 (300, 200) 、半径为 50 像素的黄色填充圆形。
三、绘制图像
- 首先创建一个 Image 对象,并设置其 src 属性指向要绘制的图像的路径:
javascript
var image = new Image();
image.src = 'image.jpg';
- 由于图像的加载是异步的,我们需要在图像加载完成后才能进行绘制。可以通过为 Image 对象添加 onload 事件处理程序来实现:
javascript
image.onload = function() {
// 在这里进行图像的绘制操作
};
- 以下是几种常见的 drawImage 方法的使用方式:
-
drawImage(image, x, y) :在指定的 (x, y) 坐标位置绘制原始大小的图像。
-
drawImage(image, x, y, width, height) :在指定的 (x, y) 坐标位置绘制指定大小的图像。
-
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) :从源图像的 (sx, sy) 位置开始,截取 sWidth x sHeight 大小的区域,并将其绘制到目标位置 (dx, dy) ,绘制的大小为 dWidth x dHeight 。
示例:
javascript
image.onload = function() {
ctx.drawImage(image, 50, 50);
};
四、图像处理
- 缩放
缩放图像可以通过调整 drawImage 方法中指定的绘制宽度和高度来实现。
例如,将图像缩小一半:
javascript
image.onload = function() {
ctx.drawImage(image, 0, 0, image.width / 2, image.height / 2);
};
- 旋转
旋转图像需要以下几个步骤:
首先,使用 save 方法保存当前的绘图状态,以确保后续的旋转操作不会影响到之前的绘制内容。
然后,使用 translate 方法将旋转中心移动到指定位置。
接着,使用 rotate 方法进行旋转。
最后,绘制图像,并使用 restore 方法恢复之前保存的绘图状态。
示例:
javascript
image.onload = function() {
ctx.save();
ctx.translate(200, 200);
ctx.rotate(Math.PI / 4);
ctx.drawImage(image, -image.width / 2, -image.height / 2);
ctx.restore();
};
- 像素操作
使用 getImageData 方法可以获取图像的像素数据。
getImageData 方法接受四个参数:起始的 x 坐标、起始的 y 坐标、获取的宽度和高度。
获取到的 ImageData 对象包含 width 、 height 和 data 属性。 data 属性是一个一维数组,其中每个像素由四个值(RGBA)表示,分别对应红、绿、蓝和透明度通道。
对像素数据进行处理后,使用 putImageData 方法将处理后的像素数据放回 Canvas 中。
示例:
javascript
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var i = 0; i < imageData.data.length; i += 4) {
var r = imageData.data[i];
var g = imageData.data[i + 1];
var b = imageData.data[i + 2];
var a = imageData.data[i + 3];
// 在此处进行像素级别的处理,例如调整颜色值
imageData.data[i] = 255 - r;
imageData.data[i + 1] = 255 - g;
imageData.data[i + 2] = 255 - b;
}
ctx.putImageData(imageData, 0, 0);
五、绘制文本
- 可以使用 fillText 方法绘制填充的文本,或者使用 strokeText 方法绘制文本边框。
示例:
javascript
ctx.font = '20px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas!', 50, 50);
上述代码将使用 20 像素大小的 Arial 字体,在 (50, 50) 位置绘制黑色填充的文本 "Hello Canvas!" 。
- 可以通过设置 textAlign 属性来控制文本的水平对齐方式,可选值包括 start (默认,左对齐)、 end (右对齐)、 center (居中对齐)等。
例如:
javascript
ctx.textAlign = 'center';
ctx.fillText('Centered Text', canvas.width / 2, 100);
这将在画布的中间位置绘制水平居中的文本。
- 还可以通过设置 textBaseline 属性来控制文本的垂直对齐方式,可选值包括 top 、 hanging 、 middle 、 alphabetic (默认)、 ideographic 、 bottom 等。
例如:
javascript
ctx.textBaseline = 'bottom';
ctx.fill.fillText('Bottom Aligned Text', 100, canvas.height - 20);
这将在指定位置绘制底部对齐的文本。
六、图形组合模式
- globalCompositeOperation 属性用于控制新绘制的图形与已有图形的组合方式。
常见的组合模式包括:
-
source-over :新图形覆盖在旧图形上(默认)。
-
destination-over :新图形在旧图形下面。
-
source-in :只显示新图形与旧图形重叠的部分,且新图形在旧图形内部。
-
destination-in :只显示旧图形与新图形重叠的部分,且新图形在旧图形内部。
-
source-out :只显示新图形不与旧图形重叠的部分。
-
destination-out :只显示旧图形不与新图形重叠的部分。
-
source-atop :只显示新图形与旧图形重叠的部分,以及旧图形不与新图形重叠的部分。
-
destination-atop :只显示旧图形与新图形重叠的部分,以及新图形不与旧图形重叠的部分。
-
lighter :两图形颜色值相加。
-
copy :显示新图形,删除旧图形。
-
xor :异或操作,只显示新图形与旧图形不重叠的部分以及重叠部分的颜色反转。
示例:
javascript
ctx.globalCompositeOperation = 'destination-over';
上述代码将设置组合模式为新图形在旧图形下面。
七、应用渐变
- 线性渐变
使用 createLinearGradient 方法创建线性渐变对象。
示例:
javascript
var linearGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
linearGradient.addColorStop(0,'red');
linearGradient.addColorStop(1, 'blue');
ctx.fillStyle = linearGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
在上述代码中,首先创建了一个从画布左上角到右上角的线性渐变对象。然后,通过 addColorStop 方法添加颜色停止点,0 表示起点位置,1 表示终点位置。最后,将渐变设置为填充样式,并绘制一个填充矩形。
- 径向渐变
使用 createRadialGradient 方法创建径向渐变对象。
示例:
javascript
var radialGradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
radialGradient.addColorStop(0,'red');
radialGradient.addColorStop(1, 'blue');
ctx.fillStyle = radialGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
上述代码创建了一个以画布中心为圆心,从半径 0 到半径 canvas.width / 2 的径向渐变,并进行了填充绘制。
八、绘制阴影
- 可以通过以下几个属性来设置阴影效果:
-
shadowColor :阴影的颜色。
-
shadowBlur :阴影的模糊程度。
-
shadowOffsetX :阴影在 x 方向的偏移量。
-
shadowOffsetY :阴影在 y 方向的偏移量。
示例:
javascript
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
上述代码设置了一个半透明的黑色阴影,模糊程度为 10 像素,在 x 方向偏移 5 像素,在 y 方向偏移 5 像素。