简述
- 通过
getImageData
方法取得图像的原始数据,这个原始数据中包含有width
,height
,data
三个属性,其中data
是一个数组,包含有每一个像素的rgba值。也就是说data
数组每4个元素为一组rgba值,第一个像素就保存在index为0到3的元素中。
- 问题:非同源图像数据不可读取。解决方法详见 解决canvas图片getImageData,toDataURL跨域问题
- 问题:本地图片无法通过getImageData方法读取图像数据。解决方法:通过flieReader对象的readAsDataURL方法把图片读取成Base64数据,再drawImage到画布上进行读取。
代码
灰阶过滤器
<canvas id="drawing1" width="400px" height="400px"></canvas>
<canvas id="drawing2" width="400px" height="400px"></canvas>
<hr>
<input type="file" name="点击提交图片" id="file1" accept="image/*">
<script>
var drawing1 = document.getElementById('drawing1');
var drawing2 = document.getElementById('drawing2');
var file1 = document.getElementById('file1');
if (drawing1.getContext) {
var context1 = drawing1.getContext('2d');
var context2 = drawing2.getContext('2d');
}
file1.addEventListener('change', function () {
var reader = new FileReader();
reader.readAsDataURL(this.files[0]);
reader.onload = function () {
var img = new Image();
img.src = reader.result;
img.onload = function () {
context1.drawImage(this, 0, 0, 400, 400);
var imgData = context1.getImageData(0, 0, 400, 400);
var data = imgData.data;
var red, green, blue, alpha, average;
for (let i = 0; i < data.length; i += 4) {
red = data[i];
green = data[i + 1];
blue = data[i + 2];
alpha = data[i + 3];
average = Math.floor((red + green + blue) / 3);
data[i] = data[i + 1] = data[i + 2] = average;
}
imgData.data = data;
context2.putImageData(imgData, 0, 0);
}
}
}, false);
</script>
示意动画
更新负色滤镜
- 负色滤镜呈现一种胶片的质感。其原理是将当前r,g,b颜色分别用最大值255减去。例如rgb(100,150,200)的负色为rgb(155,105,55);
修改部分代码为
data[i] = 255 - data[i];
data[i + 1] = 255 - data[i + 1];
data[i + 2] = 255 - data[i + 2];
示意动画
更新灰色调滤镜
更新部分代码为
data[i] = data[i] * 0.272 + data[i + 1] * 0.534 + data[i + 2] * 0.131;
ata[i + 1] = data[i] * 0.349 + data[i + 1] * 0.686 + data[i + 2] * 0.168;
data[i + 2] = data[i] * 0.393 + data[i + 1] * 0.769 + data[i + 2] * 0.189;
示意图