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。若为小数,则取整,取整的方法是银行家舍入。
- data:Uint8ClampedArray [0,1,2,3, 4,5,6,7,8,9,10,11,12,13,14,15]
建立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)
获取ImageData
ctx.getImageData(0,0,width,height);
const canvas=document.getElementById('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;
ctx.drawImage(img,0,0);
const imgData=ctx.getImageData(0,0,width,height);
ctx.putImageData(
imgData,
0,height,
150,150,
100,100
)
};
像素遍历
逐像素遍历
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)
}
行列遍历
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.299*r + 0.587*g + 0.114*b ;
const canvas=document.getElementById('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;
function draw(){
const {width,height}=img;
ctx.drawImage(img,0,0);
const imgDt=ctx.getImageData(0,0,width,height);
const data=imgDt.data;
console.log(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;
}
ctx.putImageData(imgDt,0,height);
}
图像马赛克
- 获取一区域的像素颜色,然后将此颜色赋给此区域的所有像素。
const canvas=document.getElementById('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=5;
function render() {
const {width,height}=img;
ctx.drawImage(img,0,0);
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);
}
}
}
- const i=(y*width+x)*4;的原理如下:
- 画布的 w=2, h=2 ,data=[0,1,2,3, 4,5,6,7,8,9,10,11,12,13,14,15]
- 求:data 中求r 的索引位置ind,由公式 ind=(y*w+x)*4 得:
y , x
0 , 0 - (0*2+0)*4 = 0
0 , 1 - (0*2+1)*4 = 4
1 , 0 - (1*2+0)*4 = 8
1 , 1 - (y*w+x)*4 = ?
|