HTML5canvas实现高斯模糊、刮刮乐

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>

猜你喜欢

转载自blog.csdn.net/zyz00000000/article/details/82729731