1.1 图形平移
语法:
代码语言:javascript复制//x:表示图形在x轴方向移动的距离
//y:表示图形在y轴方向移动的距离
cxt.translate(x, y);
注:对于Canvas来说,“状态”都必须在“动作”之前定义。在默认情况下,Canvas会把所有绘制的图形都保留下来,如果不想保留之前绘制的图形,在绘制新图形之前需要把这个Canvas清空,然后再去绘制新的图形。
1.2 图形缩放
语法:
代码语言:javascript复制//x:表示图形在x轴方向的缩放倍数
//y:表示图形在y轴方向的缩放倍数
//当x或y取值0~1之间时,图形进行缩小;取值大于1时,图形进行放大
cxt.scale(x, y);
注:scale()方法会改变图形的以下几点:
1)左上角坐标;
2)宽度或高度;
3)线条宽度。
1.3 图形旋转
语法:
代码语言:javascript复制//angle:表示图形旋转饿角度,取值为-Math.PI*2 ~ Math.PI*2
//当angle < 0时,图形逆时针旋转,当angle > 0 时,图形顺时针旋转
cxt.rotate(angle);
默认情况下,图形旋转是以Canvas坐标原点为旋转中心的,如果我们想要以某一点为旋转中心,可以先使用translate(x, y),然后再使用rotate()方法。
在实际开发中,可以使用translate()方法结合图形的长宽将旋转中心移动到图形中心上。
变形操作处了可以用于图形,也可以用于文字和图片。
2. 像素操作
2.1 获取一张图片的像素数据
语法:
代码语言:javascript复制//x、y表示所选图片区域的坐标
//width、height表示所选图片区域的宽度和高度
let imgData = cxt.getImageData(x, y, width, height);
let data = imgData.data;
getImageData()方法返回一个canvasPixelArray对象,该对象有个data属性,是用来保存一张图片像素数据的数组,数组取值如[r1, g1, b1, a1, r2, g2, b2, a2, ......]。
2.2 输出一张图片的像素数据
语法:
代码语言:javascript复制//image:表示重新绘制的图形,也就是用getImageData()方法获取的canvasPixelArray对象
//x、y:表示重新绘制图形左上角饿横坐标和纵坐标
cxt.putImageData(image, x, y);
2.3 反转效果
反转效果,也叫“颜色反转”,是指图片颜色颠倒效果。实际算法是:红、绿、蓝这三个通道的像素取各自的相反值,即255-原值。
语法:
代码语言:javascript复制for(let i = 0; i < data.length; i = 4){
data[i 0] = 255 - data[i 0];
data[i 1] = 255 - data[i 1];
data[i 2] = 255 - data[i 2];
}
这节相关代码继续添加到 HTML5 Canvas开发详解(3) -- 图片操作 的my-canvas-img.vue组件中。
示例代码:
代码语言:javascript复制//反转效果
reversePixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
data[i] = 255 - data[i];
data[i 1] = 255 - data[i 1];
data[i 2] = 255 - data[i 2];
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.4 黑白效果
黑白效果,也叫灰度图(average),是指将彩色图片转换成黑白图片。实现算法是:首先取红、绿、蓝三个通道的平均值,也就是 (data[i 0] data[ i 1] data[i 2]) / 3,然后data[i 0]、data[i 1]和data[i 2]全部保存为这个平均值即可。
语法:
代码语言:javascript复制for(let i = 0; i < data.length; i = 4){
let average = (data[i 0] data[ i 1] data[i 2]) / 3;
data[i 0] = average;
data[i 1] = average;
data[i 2] = average;
}
示例代码:
代码语言:javascript复制//黑白效果
averagePixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
let average = (data[i] data[ i 1] data[i 2]) / 3;
data[i] = average;
data[i 1] = average;
data[i 2] = average;
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.5 亮度效果
亮度效果(brightness),是指让图片变得更亮或者更暗。实现算法是:将红、绿、蓝三个通道值分别同时加上一个正值或者负值。
语法:
代码语言:javascript复制for(let i = 0; i < data.length; i = 4){
let a = 50;
data[i] = a;
data[i 1] = a;
data[i 2] = a;
}
示例代码:
代码语言:javascript复制//亮度效果
brightnessPixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
let a = 50;
data[i] = a;
data[i 1] = a;
data[i 2] = a;
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.6 复古效果
复古效果(sepia),是指使得图片有一种古旧效果。实现算法:将红、绿、蓝三个通道分别取这个三个值的某种加权平均值。
语法:
代码语言:javascript复制for(let i = 0; i < data.length; i = 4){
let r = data[i];
let g = data[i 1];
let b = data[i 2];
data[i] = r * 0.39 g * 0.76 b * 0.18;
data[i 1] = r * 0.35 g * 0.68 b * 0.16;
data[i 2] = r * 0.27 g * 0.53 b * 0.13;
}
示例代码:
代码语言:javascript复制//复古效果
sepiaPixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
let r = data[i];
let g = data[i 1];
let b = data[i 2];
data[i] = r * 0.39 g * 0.76 b * 0.18;
data[i 1] = r * 0.35 g * 0.68 b * 0.16;
data[i 2] = r * 0.27 g * 0.53 b * 0.13;
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.7 红色蒙版
红色蒙版,指的是让图片呈现一种偏红的效果。实现算法是:将红色通道(r)赋值为红、绿、蓝这三个的平均值,并且将绿通道和蓝通道都赋值为0。
语法:
代码语言:javascript复制for(let i = 0; i < data.length; i = 4){
let r = data[i];
let g = data[i 1];
let b = data[i 2];
let average = (r g b) / 3;
data[i] = average;
data[i 1] = 0;
data[i 2] = 0;
}
示例代码:
代码语言:javascript复制//红色蒙版效果
redMaskPixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
let r = data[i];
let g = data[i 1];
let b = data[i 2];
let average = (r g b) / 3;
data[i] = average;
data[i 1] = 0;
data[i 2] = 0;
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.8 透明处理
对于透明处理,我们都是在得到像素数组后,将该数组中每一个像素的透明度乘以n,然后保存像素数组,最后使用putImageData()方法将图像重新绘制在画布上。
语法:
代码语言:javascript复制//n的取值范围为0.0~1.0
for(let i = 0; i < data.length; i = 4){
data[i 3] = data[i 3] * n;
}
示例代码:
代码语言:javascript复制 //透明效果
transPixel(cxt){
cxt.drawImage(this.imgObj, 10, 10, 120, 80);
let imgData = cxt.getImageData(10, 10, 120, 80);
let data = imgData.data;
for(let i = 0; i < data.length; i = 4){
data[i 3] = data[i 3] * 0.3;
}
cxt.putImageData(imgData, 150, 10);
}
示例效果:
2.9 createImageData()方法
用于在画布中创建一个区域,使得这个区域可以进行像素操作。
语法:
代码语言:javascript复制//格式一
//sw、sh:分别表示要创建区域的宽度的高度
cxt.createImageData(sw, sh);
//格式二
//imageData:像素对象,表示要“创建区域”的宽度和高度与这个像素对象的宽度和高度相等
cxt.createImageData(imageData);
getImageData()和putImageData()配合使用是对一张图片进行像素操作,createImageData()和putImageData()配合使用是对一个区域进行像素操作。
示例代码:
代码语言:javascript复制//创建像素操作区域
createPixelArea(cxt){
cxt.drawImage(this.imgObj, 0, 0, 120, 80);
let imgData1 = cxt.getImageData(0, 0, 120, 80);
let imgData2 = cxt.createImageData(imgData1);
let data = imgData2.data;
for(let i = 0; i < 100 * 100 * 4; i = 4){
data[i] = 0;
data[i 1] = 0;
data[i 2] = 255;
data[i 3] = 255;
}
cxt.putImageData(imgData2, 150, 0);
}
示例效果: