1.理解ImageData() 对象的获取方式。
1.1. ImageData 是什么?
ImageData 是图片的数据化,它具备以下属性:
- data:Uint8ClampedArray [r,g,b,a, r,g,b,a, r,g,b,a, r,g,b,a]
- width:整数
- heidth:整数
注:Uint8ClampedArray 翻译过来是 8位无符号整型固定数组,其取值范围是[0,255]。若小于0,则为0,大于255,则为255。若为小数,则取整,取整的方法是银行家舍入。
1.2 怎么拿到 ImageData() 对象?
- 直接建立ImageData() 对象(相当于自己新建了一张图片)。
-
new ImageData()
new ImageData(width, height)
new ImageData(Uint8ClampedArray, width, height)
-
ctx.createImageData()
ctx.createImageData(width, height)
ctx.createImageData(ImageData)
-
获取canvas 的ImageData() 对象(可以以此原理获取真实图片的数据)
ctx.getImageData(x, y, width, height)
-
在canvas 中显示ImageData
使用: putImageData(ImageData, dx, dy, x, y, w, h)
const imgDt=ctx.createImageData(width,height);
console.log('imgDt', imgDt)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ImageData </title>
<style>
body{margin: 0;overflow: hidden}
#canvas{background: antiquewhite;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
//canvas充满窗口
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//画笔
const ctx=canvas.getContext('2d');
/*
* 图片尺寸:宽,高
* */
const [width,height]=[400,200];
/*ImageData 对象的建立
* new ImageData(Uint8ClampedArray, width, height)
* new ImageData( width, height)
* */
/*const imgDt=new ImageData(width,height);
imgDt.data.forEach((ele,ind)=>{
imgDt.data[ind]=255;
})
console.log(imgDt);
ctx.putImageData(imgDt,0,0);*/
/*用上下文建立ImageData 对象
* ctx.createImageData(width, height)
* ctx.createImageData(ImageData)
* */
const imgDt=ctx.createImageData(width,height);
imgDt.data.forEach((ele,ind)=>{
imgDt.data[ind]=255;
})
ctx.putImageData(imgDt,0,0);
/*getImageData(x, y, width, height) 获取canvas 中的像素*/
const imgDt2=ctx.getImageData(0,0,1,1);
console.log(imgDt2);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>putImageData</title>
<style>
body{margin: 0;overflow: hidden}
#canvas{background: antiquewhite;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
//canvas充满窗口
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
const img=new Image();
img.src='./images/dog.jpg';
img.onload=function(){
//获取图片宽高
const {width,height}=img;
/*1.在canvas 中绘制图像*/
ctx.drawImage(img,0,0);
/*2.从canvas 中获取图像的ImageData*/
const imgDt=ctx.getImageData(0,0,width,height);
/*3.在canvas 中显示ImageData*/
ctx.putImageData(
imgDt,
0,height,
width/2,height/2,width/2,height/2);
};
</script>
</body>
</html>
-
理解 ImageData 中的像素集合和图像栅格的对应关系
ImageData 对象的属性:
data:Uint8ClampedArray [0,1,2,3, 4,5,6,7,8,9,10,11,12,13,14,15]
width:2
heidth:2
-
遍历像素的方法
- 1.逐像素遍历:每隔4 个数据遍历一次,简单快捷
for(let i=0;i<arr.length;i+=4){
let r=data[i+0];
let g=data[i+1];
let b=data[i+2];
let a=data[i+3];
console.log(r,g,b,a)
}
- 2.行列遍历:基于行列遍历,可获取像素点的位置信息
for(let y=0;y<h;y++){
for(let x=0;x<w;x++){
let ind=(y*w+x)*4;
let r=data[ind];
let g=data[ind+1];
let b=data[ind+2];
let a=data[ind+3];
console.log(r,g,b,a)
}
}
- 图像置灰
要点:灰度算法 const lm =0.299r + 0.587g + 0.114*b ;
操作像素:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图像置灰</title>
<style>
body{margin: 0;overflow: hidden}
#canvas{background: antiquewhite;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
//canvas充满窗口
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
const img=new Image();
img.src='./images/river.jpg';
img.onload=draw;
/*灰度算法: 0.299*r+0.587*g+0.114*b */
function draw(){
//图像尺寸
const {width,height}=img;
/*1.在canvas 中绘制图像*/
ctx.drawImage(img,0,0);
/*2.从canvas 中获取图像的ImageData*/
const imgDt=ctx.getImageData(0,0,width,height);
const data=imgDt.data;
/*像素遍历*/
// 修改像素中的数据
for(let i=0;i<data.length;i+=4){
const [r,g,b]=[
data[i],
data[i+1],
data[i+2],
]
const lm=0.299*r+0.587*g+0.114*b;
data[i]=lm;
// data[i+1]=lm;
// data[i+2]=lm;
}
/*3.在canvas 中显示ImageData*/
ctx.putImageData(imgDt,0,height);
}
</script>
</body>
</html>
- 马赛克效果:
要点:获取一区域的像素颜色,然后将此颜色赋给此区域的所有像素。
原图:
设置的马赛克效果:
8. 求r 在像素集合里的索引位置 ind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>马赛克效果</title>
<style>
body{margin: 0;overflow: hidden}
#canvas{background: antiquewhite;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas=document.getElementById('canvas');
//canvas充满窗口
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
const ctx=canvas.getContext('2d');
//图像源
const img=new Image();
img.src='./images/wns.jpg';
img.onload=render;
//色块尺寸
let size=50;
function render() {
//图像尺寸
const {width,height}=img;
/*1.在canvas 中绘制图像*/
ctx.drawImage(img,0,0);
/*2.从canvas 中获取图像的ImageData*/
const imgDt=ctx.getImageData(0,0,width,height);
const data=imgDt.data;
/*行列遍历*/
for(let y=0;y<height;y+=size){
for(let x=0;x<width;x+=size){
const i=(y*width+x)*4;
const [r,g,b]=[
data[i],
data[i+1],
data[i+2],
]
ctx.fillStyle=`RGB(${r},${g},${b})`;
ctx.fillRect(x,y,size,size);
}
}
}
</script>
</body>
</html>