HTML5   发布时间:2022-04-25  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了HTML5 模糊图片大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前几天听了刘立老师的图像处理一门课后,感觉图像处理很有意思,正好最近也在学习js,于是花了点时间做了一个简易处理程序,功能很简单,就是去除脸上的黑头和痘痘,哈哈。

效果图:(处理前,图片来源于网络)

HTML5 模糊图片


处理后:

HTML5 模糊图片



可以看到效果确实挺明显的哈,这也是html5的强大之处。

下面来说明这个程序的原理。


黑头和痘痘的恼人之处在于与自己的皮肤格格不入,每次自拍看到自己白白的脸上有那么几颗黑点显得格外的突兀,那么我们要想到,如何去除这些显眼的地方呢?

因为图片都是一个个像素点组成的,每个像素点的颜色不同才构成了一个绚丽多彩的图片,比较通用的一种描述颜色的方式是用RGB色彩模式描述,通过红(R)、绿(G)、蓝(B)三种颜色的变化以及它们之间的叠加来得到各种各样的颜色,其中每种颜色由浅到深用数字表示为0~255,假设有一个3* 3 像素的图片,其中每个像素的颜色都是(255,0),那么这个图片表现出来的就是一个3* 3的红色正方形,即:

(255,0) (255,0) (255,0)

(255,0)

(255,0)

HTML5 模糊图片


那假设中间有个点颜色变为(0,0),如下:

(255,0)    (0,0)

HTML5 模糊图片


可以看到中间的颜色变为了黑色,格外显眼,就好像白皙的皮肤上多了一颗显眼的黑头!

那么如何去掉这个恼人的黑点呢? 很容易想到,将其与周边颜色同化即可,也就是说,我们可以扫描整个图片,然后找出那些与周围颜色不同的点,将其颜色改为与周围环境相似即可。

是不是很简单,下面演示代码


首先是写出页面的主要结构:

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <style>
        #img_1 {
            margin: 10px;
        }

        canvas {
            border: 1px #c1c1c1 solid;
        }
    </style>
</head>
<body>
    <img id="img_1" src="image/aa.jpg" style="display: inline-block"/>
    <canvas id="canvas_1"></canvas>
</body>
</html>


img存放原图,方便处理后进行对比。canvas是html5中的标签,也是这个程序的关键所在,我们对图像的处理都在canvas中进行。

接下来写js代码

首先,初始化canvas

<script>
    window.onload = function () {

        var canvas = document.getElementById("canvas_1");
        var img = document.getElementById("img_1");

        canvas.width = img.width + 20;
        canvas.height = img.height + 20;
        var context = canvas.getContext("2d");

        //画出图像
        context.drawImage(img,10,10);
    };
</script>
因为我想通过鼠标拖拽来处理相应位置的图片,所以接下来给画布添加鼠标监听,另外鼠标拖拽时需要有一个影响范围,用radius表示。

    var isDrag = false;
    var radius = 20;
    window.onload = function () {

        var canvas = document.getElementById("canvas_1");
        var img = document.getElementById("img_1");

        canvas.width = img.width + 20;
        canvas.height = img.height + 20;
        var context = canvas.getContext("2d");

        //画出图像
        context.drawImage(img,10);

        //添加鼠标监听
        canvas.onmousedown = function(E){
            isDrag = true;
        };

        canvas.onmouseup = function(){
            isDrag = false;
            this.style.cursor = "default";
        };

        canvas.onmousemove = function(E){
            if(isDrag){
                this.style.cursor = "pointer";
                // 获取鼠标相对于父元素的坐标
                var x = e.clientX + document.body.scrollLeft - document.body.clientLeft;
                var y = e.clientY + document.body.scrollTop - document.body.clientTop - canvas.offsetTop;
                handleArea(context,x - radius - 10,y - radius,radius * 2,radius * 2);
            }
        };
    };

那么在handleArea里面就是改变图像的代码了,其中参数分别为canvas的上下文、处理部分的左上角横坐标、纵坐标、处理部分的宽、处理部分的高,因为在css里面对img设置了margin,为了好看,我们也在canvas里的10,10处开始绘画。

修改图片部分像素的颜色是通过改变其RGB值实现的,为了方便保存和修改完之后合成RGB值,我创建了三个数组来分别保存每个像素点的RGB值:

var red2 = [],green2 = [],blue2 = [];

因为js不能直接创建二维数组,所以对其初始化

function initArr2(arr,sizE) {
      for (var i = 0; i < size; i++) {
          arr[i] = [];
      }
}
接下来就是第一个重点了,取出每个像素点的RGB值并保存

            //获取像素信息
            var imageData = context.getImageData(start_x,start_y,width,height);

            //取出像素信息
            var col = 0,row = 0;
            for (var i = 0; i < imageData.data.length; i += 4) {

                red2[row][col] = imageData.data[i];<span style="white-space:pre">	</span>//获取红色值
                green2[row][col] = imageData.data[i + 1];<span style="white-space:pre">	</span>//获取绿色值
                blue2[row][col] = imageData.data[i + 2];<span style="white-space:pre">	</span>//获取蓝色值

                coL++;
                if (col == width) {
                    col = 0;
                    row++;
                }
            }
getImageData可以复制画布上指定矩形的像素数据,对于imageData中的每个像素,都存在四方面的信息,即RGBA值,分别是RGB加Alpha(透明度),这些数据以数组的形式按顺序存放于imageData中的data属性里。可以按如上方式依次取出,这里我们暂时不需要透明度,所以只取前3个。

取完RGB颜色之后即是处理的时候了,既然我们现在已经将每个点的RGB值都拿到了,当然好比较每个像素点和周围像素的区别了,遍历查找即可:

function handleArray(arr) {
            for (var i = 0; i < arr.length; i++) {
                for (var j = 0; j < arr[i].length; j++) {
                    if (i > 0 && i < arr.length - 1 && j > 0 && j < arr[i].length - 1) {
                        var temp = [arr[i - 1][j - 1],arr[i][j - 1],arr[i + 1][j - 1],arr[i - 1][j],arr[i + 1][j],arr[i - 1][j + 1],arr[i][j + 1],arr[i + 1][j + 1]];
                        var avg = temp.getAvg();
                        if (Math.abs(arr[i][j] - avg) > 0) {
                            arr[i][j] = avg;
                        }
                    }
                }
            }
        }
这里用到数组取平均值,为了重复使用,在原型中加入了方法

/**
 * 获取数组平均数
 * @returns {number}
 */
Array.prototype.getAvg = function(){
    var sum = 0;
    for(var i = 0; i < this.length; i++){
        sum += this[i];
    }
    return sum / this.length;
};

那么至此已经将指定位置的像素信息改变了,但是原图不会发生任何变化,因为我们并未将改变后的信息放入到图像中,放入图像用到context的 putImageData方法

            var rows = 0,cols = 0;
            for (var i = 0; i < imageData.data.length; i += 4) {
                imageData.data[i] = red2[rows][cols];
                imageData.data[i + 1] = green2[rows][cols];
                imageData.data[i + 2] = blue2[rows][cols];
                cols++;
                if (cols == width) {
                    cols = 0;
                    rows++;
                }
            }
            context.putImageData(imageData,start_x,start_y);

那么,一个简单的图像处理就做好了,全部代码如下,当然这固定了影响的范围,大家也可以根据自己需要加入<input type="range">标签,动态改变radius值,手动调整范围

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <style>
        #img_1 {
            @H_231_166@margin: 10px;
        }

        canvas {
            border: 1px #c1c1c1 solid;
        }
    </style>
</head>
<body>
    <img id="img_1" src="image/aa.jpg" style="display: inline-block"/>
    <canvas id="canvas_1"></canvas>
    <script src="js/arrayUtil.js"></script>
    <script>

        var red2 = [],green2 = [],blue2 = [];
        var isDrag = false;
        var radius = 10;
        window.onload = function () {

            var canvas = document.getElementById("canvas_1");
            var img = document.getElementById("img_1");

            canvas.width = img.width + 20;
            canvas.height = img.height + 20;
            var context = canvas.getContext("2d");

            //画出图像  context.drawImage(img,10,10);

            canvas.onmousedown = function(E){
                isDrag = true;
                console.log(e.clientY + document.body.scrollTop - document.body.clientTop - canvas.offsetTop);
            };

            canvas.onmouseup = function(){
                isDrag = false;
                this.style.cursor = "default";
            };

            canvas.onmousemove = function(E){
                if(isDrag){
                    this.style.cursor = "pointer";
                    // 获取鼠标相对于父元素的坐标  var x = e.clientX + document.body.scrollLeft - document.body.clientLeft;
                    var y = e.clientY + document.body.scrollTop - document.body.clientTop - canvas.offsetTop;
                    handleArea(context,x - radius - 10,y - radius,radius * 2,radius * 2);
                }
            };
        };

        function handleArray(arr) {
            for (var i = 0; i < arr.length; i++) {
                for (var j = 0; j < arr[i].length; j++) {
                    if (i > 0 && i < arr.length - 1 && j > 0 && j < arr[i].length - 1) {
                        var temp = [arr[i - 1][j - 1],arr[i][j - 1],arr[i + 1][j - 1],arr[i - 1][j],arr[i + 1][j],arr[i - 1][j + 1],arr[i][j + 1],arr[i + 1][j + 1]];
                        var avg = temp.getAvg();
                        if (@H_593_252@math.abs(arr[i][j] - avg) > 0) {
                            arr[i][j] = avg;
                        }
                    }
                }
            }
        }

        function initArr2(arr,sizE) {
            for (var i = 0; i < size; i++) {
                arr[i] = [];
            }
        }

        /**  *  * @param context  * @param start_x 此x 为相对于canvas右下10px的坐标  * @param start_y  * @param width  * @param height  */  function handleArea(context,start_x,start_y,width,height){
            initArr2(red2,height);
            initArr2(green2,height);
            initArr2(blue2,height);

            //获取像素信息  var imageData = context.getImageData(start_x,height);

            //取出二维数组  var col = 0,row = 0;
            for (var i = 0; i < imageData.data.length; i += 4) {
                red2[row][col] = imageData.data[i];
                green2[row][col] = imageData.data[i + 1];
                blue2[row][col] = imageData.data[i + 2];

                col++;
                if (col == width) {
                    col = 0;
                    row++;
                }
            }

            handleArray(red2);
            handleArray(green2);
            handleArray(blue2);

            var rows = 0,cols = 0;
            for (var i = 0; i < imageData.data.length; i += 4) {
                imageData.data[i] = red2[rows][cols];
                imageData.data[i + 1] = green2[rows][cols];
                imageData.data[i + 2] = blue2[rows][cols];
                cols++;
                if (cols == width) {
                    cols = 0;
                    rows++;
                }
            }
            context.putImageData(imageData,start_y);
        }
    </script>
</body>

</html>

arrayUtil.js

/**  * 获取数组平均数  * @returns {number}  */ Array.prototype.getAvg = function(){
    var sum = 0;
    for(var i = 0; i < this.length; i++){
        sum += this[i];
    }
    return sum / this.length;
};
博主也在学习js当中,文章难免有不足之处,还望大家指正!

大佬总结

以上是大佬教程为你收集整理的HTML5 模糊图片全部内容,希望文章能够帮你解决HTML5 模糊图片所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。