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 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
喵叔哟7 分钟前
重构代码之用委托替代继承
开发语言·重构
lzb_kkk13 分钟前
【JavaEE】JUC的常见类
java·开发语言·java-ee
SEEONTIME13 分钟前
python-24-一篇文章彻底掌握Python HTTP库Requests
开发语言·python·http·http库requests
起名字真南32 分钟前
【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案
开发语言·c++·leetcode
tyler_download43 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
小小小~43 分钟前
qt5将程序打包并使用
开发语言·qt
hlsd#44 分钟前
go mod 依赖管理
开发语言·后端·golang
小春学渗透1 小时前
Day107:代码审计-PHP模型开发篇&MVC层&RCE执行&文件对比法&1day分析&0day验证
开发语言·安全·web安全·php·mvc
四喜花露水1 小时前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js