1.高斯模糊(Gaussian blur)
原理:将图片插入到canvas中,将canvas中的图片,getImageData得到图片的像素值,用高斯模糊函数进像素值进行处理后,再把值putImageData放到canvas中,就实现了图片的高斯模糊处理。
高斯模糊函数中的逻辑:
注意:此处是window整个页面进行加载,不可以用img来调用onload方法,会报错:高斯函数未被定义的错误。
注意:getImageData、putImageData两个方法在服务器中使用有效。
HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>gauss</title>
<style>
#data{
width: 400px;
height: 300px;
}
</style>
</head>
<body>
<img id="data" src="timg.jpg" alt="">
<canvas id="canvas" height="500" width="500"></canvas>
<script src="gaussFun.js"></script>
<script>
var oImg = document.getElementById('data');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var oData,newSrc;
window.onload = function () {
ctx.drawImage(oImg,0,0,400,300);
oData = ctx.getImageData(0,0,400,300);
newSrc = gaussBlur(oData);
ctx.putImageData(newSrc, 0, 0);
}
</script>
</body>
</html>
高斯模糊函数:
function gaussBlur(imgData) {
var pixes = imgData.data;
var width = imgData.width;
var height = imgData.height;
var gaussMatrix = [],
gaussSum = 0,
x, y,
r, g, b, a,
i, j, k, len;
var radius = 10;
var sigma = 5;
a = 1 / (Math.sqrt(2 * Math.PI) * sigma);
b = -1 / (2 * sigma * sigma);
//生成高斯矩阵
for (i = 0, x = -radius; x <= radius; x++, i++){
g = a * Math.exp(b * x * x);
gaussMatrix[i] = g;
gaussSum += g;
}
//归一化, 保证高斯矩阵的值在[0,1]之间
for (i = 0, len = gaussMatrix.length; i < len; i++) {
gaussMatrix[i] /= gaussSum;
}
//x 方向一维高斯运算
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
r = g = b = a = 0;
gaussSum = 0;
for(j = -radius; j <= radius; j++){
k = x + j;
if(k >= 0 && k < width){//确保 k 没超出 x 的范围
//r,g,b,a 四个一组
i = (y * width + k) * 4;
r += pixes[i] * gaussMatrix[j + radius];
g += pixes[i + 1] * gaussMatrix[j + radius];
b += pixes[i + 2] * gaussMatrix[j + radius];
// a += pixes[i + 3] * gaussMatrix[j];
gaussSum += gaussMatrix[j + radius];
}
}
i = (y * width + x) * 4;
// 除以 gaussSum 是为了消除处于边缘的像素, 高斯运算不足的问题
// console.log(gaussSum)
pixes[i] = r / gaussSum;
pixes[i + 1] = g / gaussSum;
pixes[i + 2] = b / gaussSum;
// pixes[i + 3] = a ;
}
}
//y 方向一维高斯运算
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
r = g = b = a = 0;
gaussSum = 0;
for(j = -radius; j <= radius; j++){
k = y + j;
if(k >= 0 && k < height){//确保 k 没超出 y 的范围
i = (k * width + x) * 4;
r += pixes[i] * gaussMatrix[j + radius];
g += pixes[i + 1] * gaussMatrix[j + radius];
b += pixes[i + 2] * gaussMatrix[j + radius];
// a += pixes[i + 3] * gaussMatrix[j];
gaussSum += gaussMatrix[j + radius];
}
}
i = (y * width + x) * 4;
pixes[i] = r / gaussSum;
pixes[i + 1] = g / gaussSum;
pixes[i + 2] = b / gaussSum;
}
}
//end
return imgData;
}
2. 刮刮乐
原理:将canvas背景用图片设置,canvas内容用刮刮乐灰色效果,然后鼠标按下、鼠标移动、鼠标抬起,完成清除canvas内容的操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas id="canv" width="400" height="400"></canvas>
<script>
var oCanvas = document.getElementById('canv'),
ctx = oCanvas.getContext('2d'),
w = oCanvas.width,
h = oCanvas.height,
lastPiont = {},
nowPoint = {};
function init(){
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0,w, h);
ctx.globalCompositeOperation = 'destination-out';
var img = new Image();
img.src = './1.jpeg';
img.onload = function(){
oCanvas.style.backgroundImage = 'url(' + img.src + ')';
oCanvas.addEventListener('mousedown', downFunc, false);
}
}
init();
function downFunc(e){
lastPiont.x = e.clientX - oCanvas.offsetLeft;
lastPiont.y = e.clientY - oCanvas.offsetTop;
oCanvas.addEventListener('mousemove', moveFunc, false);
document.addEventListener('mouseup', upFunc, false);
}
function moveFunc(e){
nowPoint.x = e.clientX - oCanvas.offsetLeft;
nowPoint.y = e.clientY - oCanvas.offsetTop;
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.lineWidth = 40;
ctx.lineCap = 'round';
ctx.moveTo(lastPiont.x, lastPiont.y);
ctx.lineTo(nowPoint.x, nowPoint.y);
ctx.stroke();
ctx.arc(nowPoint.x, nowPoint.y, 20, 0, Math.PI *2);
ctx.closePath();
ctx.fill();
lastPiont.x = nowPoint.x;
lastPiont.y = nowPoint.y;
}
function upFunc(){
oCanvas.removeEventListener('mousemove', moveFunc, false);
document.removeEventListener('mouseup', upFunc, false);
clearCanvas();
}
function clearCanvas(){
var d = ctx.getImageData(0, 0, w, h),
c = 0,
len = d.data.length;
for(var i = 0; i < len; i += 4){
if(d.data[i] === 0){
c++;
}
}
if(c > len/4 *0.7){
ctx.clearRect(0, 0, w, h);
}
}
</script>
</body>
</html>