JavaScript和 HTML5 Canvas实现图像绘制与处理

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');

二、绘制基本图形

  1. 矩形
  • 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 像素。

  1. 线条
  • 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) 的直线,并使用绿色绘制线条。

  1. 圆形

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 像素的黄色填充圆形。

三、绘制图像

  1. 首先创建一个 Image 对象,并设置其 src 属性指向要绘制的图像的路径:
javascript 复制代码
var image = new Image();
image.src = 'image.jpg'; 
 
  1. 由于图像的加载是异步的,我们需要在图像加载完成后才能进行绘制。可以通过为 Image 对象添加 onload 事件处理程序来实现:
javascript 复制代码
image.onload = function() {
    // 在这里进行图像的绘制操作
};
  1. 以下是几种常见的 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); 
};

四、图像处理

  1. 缩放

缩放图像可以通过调整 drawImage 方法中指定的绘制宽度和高度来实现。

例如,将图像缩小一半:

javascript 复制代码
image.onload = function() {
    ctx.drawImage(image, 0, 0, image.width / 2, image.height / 2); 
};
 
  1. 旋转

旋转图像需要以下几个步骤:

首先,使用 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();
};
  1. 像素操作

使用 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);

五、绘制文本

  1. 可以使用 fillText 方法绘制填充的文本,或者使用 strokeText 方法绘制文本边框。

示例:

javascript 复制代码
ctx.font = '20px Arial';
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas!', 50, 50);

上述代码将使用 20 像素大小的 Arial 字体,在 (50, 50) 位置绘制黑色填充的文本 "Hello Canvas!" 。

  1. 可以通过设置 textAlign 属性来控制文本的水平对齐方式,可选值包括 start (默认,左对齐)、 end (右对齐)、 center (居中对齐)等。

例如:

javascript 复制代码
ctx.textAlign = 'center';
ctx.fillText('Centered Text', canvas.width / 2, 100);

这将在画布的中间位置绘制水平居中的文本。

  1. 还可以通过设置 textBaseline 属性来控制文本的垂直对齐方式,可选值包括 top 、 hanging 、 middle 、 alphabetic (默认)、 ideographic 、 bottom 等。

例如:

javascript 复制代码
ctx.textBaseline = 'bottom';
ctx.fill.fillText('Bottom Aligned Text', 100, canvas.height - 20);

这将在指定位置绘制底部对齐的文本。

六、图形组合模式

  1. 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';
 

上述代码将设置组合模式为新图形在旧图形下面。

七、应用渐变

  1. 线性渐变

使用 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 表示终点位置。最后,将渐变设置为填充样式,并绘制一个填充矩形。

  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 的径向渐变,并进行了填充绘制。

八、绘制阴影

  1. 可以通过以下几个属性来设置阴影效果:
  • 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 像素。

相关推荐
故事不长丨7 小时前
C#正则表达式完全攻略:从基础到实战的全场景应用指南
开发语言·正则表达式·c#·regex
源心锁7 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
哈库纳玛塔塔7 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
phltxy8 小时前
从零入门JavaScript:基础语法全解析
开发语言·javascript
Kagol8 小时前
JavaScript 中的 sort 排序问题
前端·javascript
天“码”行空9 小时前
java面向对象的三大特性之一多态
java·开发语言·jvm
cos10 小时前
Fork 主题如何更新?基于 Ink 构建主题更新 CLI 工具
前端·javascript·git
odoo中国10 小时前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
代码N年归来仍是新手村成员10 小时前
【Java转Go】即时通信系统代码分析(一)基础Server 构建
java·开发语言·golang
Z1Jxxx11 小时前
01序列01序列
开发语言·c++·算法