cavas的使用汇总[通俗易懂]

cavas的使用汇总[通俗易懂]canvas图像处理汇总一、canvas的情况canvas自从出来了之后,在前端的图像处理上面提供了各种各样的遍历,虽然很多的操作其实都是要应用到算法的,但是这个也给前端提供了很多的可能性,其中最

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

canvas图像处理汇总

 

一、canvas的情况

canvas自从出来了之后,在前端的图像处理上面提供了各种各样的遍历,虽然很多的操作其实都是要应用到算法的,但是这个也给前端提供了很多的可能性,其中最终要的一个canvas函数(至少我认为)就是getImageData,这个函数可以提取图像每个像素的RGBA值。因为有这个函数所有才有丰富多彩的canvas图像处理。

二、预备知识

 2.1 获取一个canvas对象

复制代码
<canvas id="test"></canvas>
<script>
    var test = document.querySelector("#test");// 方法一
    var test_1=document.getElementById("test");// 方法二
    console.log(test);
    console.log(test_1);
</script>
复制代码

2.2 创建一个画布的空间类型(2D,3D)

创建一个2D的画布

var ctx = test.getContext("2d");

2.3 getImageData对象

getImageData对象可以获取画布中的图片对应的所有像素的RGBA值,这个有利于我们对图片进行重新的计算。在使用这个属性的时候,需要配置好HTTP的访问环境。

2.4 Uint8ClampedArray

这个代表的是一个无类型8位的字符串,也就是说明最多存储到255

2.5 Uint8ClampedArray与getImageData对象

Uint8ClampedArray包含在getImageData对象中,getImageData除了有Uint8ClampedArray之外,还有获取图片数据的长度和宽度。

 

三、多种图片效果canvas实现

1. 原图

2. 反色(负片)效果

3. 去色效果

4. 单色效果

5. 中国版画效果

6. 高斯模糊效果

7. 浮雕效果与刻雕效果

 

3.1 原图

 通过canvas来渲染原图,首选我们在网上随意找一张图片。

 cavas的使用汇总[通俗易懂]

  ·

复制代码
window.onload = function () {
        var img = new Image();
        img.src = "rx.jpg";
        // 加载完成图片之后才能够执行canvas的操作
        img.onload = function () {
            var canvas = document.querySelector("#canvas");
            var cxt = canvas.getContext("2d");
            canvas.width=293;
            canvas.height=220;
            cxt.drawImage(img, 0, 0, 293, 220);
        }
    }
复制代码

 

其中canvas的width,height属性都是必须要设置的,不设置的话,canvas会采用默认的width=300,height=150来设置图片。

cavas的使用汇总[通俗易懂]

3.2 反色(负片)效果 

图片反色的原理其实很简单不多做解释:将图片中的每一个元素进行如下的公式运算就可以得到最终的结果

cavas的使用汇总[通俗易懂]

 

复制代码
 window.onload = function () {
        var img = new Image();
        img.src = "rx.jpg";
        img.onload = function () {
            var canvas = document.querySelector("#canvas");
            var cxt = canvas.getContext("2d");
            canvas.width = 293;
            canvas.height = 220;
            cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
            var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
            var imageData_length = imageData.data.length / 4;
            // 解析之后进行算法运算
            for (var i = 0; i < imageData_length; i++) {
                imageData.data[i * 4] = 255 - imageData.data[i * 4];
                imageData.data[i * 4 + 1] = 255 - imageData.data[i * 4 + 1];
                imageData.data[i * 4 + 2] = 255 - imageData.data[i * 4 + 2];
            }
            cxt.putImageData(imageData, 0, 0);

        }
    }
复制代码

运行之后的效果如下:

 cavas的使用汇总[通俗易懂]

 3.3 去色效果

这里说的去色效果与第二种效果不同的是,去色效果相当于就是老旧相机拍出来的黑白照片。

要得到去色效果的照片有很多种方法,但是卤煮比较推崇的做法是采用基于人眼感觉的加权平均数来实现,这个算法的原理是采用人眼对RGB不同颜色的敏感程度不同,然后通过得出的加权平均数来运算出最后的结果

Gray = (Red * 0.3 + Green * 0.59 + Blue * 0.11)

代码如下实现:

复制代码
 window.onload = function () {
        var img = new Image();
        img.src = "rx.jpg";
        img.onload = function () {
            var canvas = document.querySelector("#canvas");
            var cxt = canvas.getContext("2d");
            canvas.width = 293;
            canvas.height = 220;
            cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
            var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
            var imageData_length = imageData.data.length / 4;
            // 解析之后进行算法运算
            for (var i = 0; i < imageData_length; i++) {
                var red = imageData.data[i * 4];
                var green = imageData.data[i * 4 + 1];
                var blue = imageData.data[i * 4 + 2];
                var gray = 0.3 * red + 0.59 * green + 0.11 * blue;
                imageData.data[i * 4] = gray;
                imageData.data[i * 4 + 1] = gray;
                imageData.data[i * 4 + 2] = gray;
            }
            cxt.putImageData(imageData, 0, 0);

        }
    }
复制代码

 

运行效果如下:

cavas的使用汇总[通俗易懂]

3.4 单色效果

单颜色效果原理就是将当前像素的其他色值去除。

假设我们要实现的单颜色效果是红色,那么实现的代码如下:

 

复制代码
 window.onload = function () {
        var img = new Image();
        img.src = "rx.jpg";
        img.onload = function () {
            var canvas = document.querySelector("#canvas");
            var cxt = canvas.getContext("2d");
            canvas.width = 293;
            canvas.height = 220;
            cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
            var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
            var imageData_length = imageData.data.length / 4;
            // 解析之后进行算法运算
            for (var i = 0; i < imageData_length; i++) {
                imageData.data[i * 4 + 1] = 0;
                imageData.data[i * 4 + 2] = 0;
            }
            cxt.putImageData(imageData, 0, 0);

        }
    }
复制代码

效果图:

cavas的使用汇总[通俗易懂]

 

 3.5 中国版画效果

中国版画不同于去色和反色的效果,在中国版画的效果中除了黑就是白色,不存在其他的颜色,下面就是一张传统的中国版画的效果。

cavas的使用汇总[通俗易懂]

 

这个的实现算法比较的灵活一般是根据你要得到的效果来进行参数配置的,原理就是通过判断当前元素的色值是否高于这个给定值,高于我们就显示为黑色,小于我们就显示为白色这样的一种方法来实现的。

按照卤煮一般的设置值来说会设置为126.因为126是2的8次方的中间数。相对来说比较的对称

实现的代码如下:

复制代码
window.onload = function () {
        var img = new Image();
        img.src = "rx.jpg";
        img.onload = function () {
            var canvas = document.querySelector("#canvas");
            var cxt = canvas.getContext("2d");
            canvas.width = 293;
            canvas.height = 220;
            cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
            var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);
            var imageData_length = imageData.data.length / 4;
            // 解析之后进行算法运算
            for (var i = 0; i < imageData_length; i++) {
                var red = imageData.data[i * 4];
                var green = imageData.data[i * 4 + 1];
                var blue = imageData.data[i * 4 + 2];
                var gray = 0.3 * red + 0.59 * green + 0.11 * blue;
                var new_black;
                if (gray > 126) {
                    new_black = 255;
                } else {
                    new_black = 0;
                }
                imageData.data[i * 4] = new_black;
                imageData.data[i * 4 + 1] = new_black;
                imageData.data[i * 4 + 2] = new_black;
            }
            cxt.putImageData(imageData, 0, 0);

        }
    }
复制代码

 

运行的效果如下:

cavas的使用汇总[通俗易懂]

如果是我们要渲染更多的黑颜色的话,我们应该要将值调高,反之将其调低,下面我们把值调到150运行一下:

cavas的使用汇总[通俗易懂]

3.6 高斯模糊效果

高斯模糊是一种两维的卷积模糊操作,简单的介绍就是通过让图片的每个像素与四周的像素按照某种权重进行分布求值,要了解具体的同学可以戳戳这里

这里我们就展示结论,推导不做介绍(二维高斯分布函数):

cavas的使用汇总[通俗易懂]

 我们直接贴出实现的代码:

复制代码
function gaussBlur(imgData) {
    console.log(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 = 30;
    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;
        }
    }
    console.log(imgData);
    return imgData;
}
复制代码

 

运行之后的效果如下:

cavas的使用汇总[通俗易懂]

 3.7 浮雕效果与刻雕效果

这里要感谢CSDN的算法专家gloomyfish,他的博文给我提供了一个好的思路,同时根据他的一个代码逻辑我们可以得出如下的公式:

cavas的使用汇总[通俗易懂]    (C常量,Xa后一个像素的RGB,Xb前一个像素的RGB)

 其中color代表的是最后的色值,Xa和Xb代表的是当前像素前后两点的RGB(中的某一个值),C代表的是一个常量【根据你的具体需要来定】

原理就是将某个像素与周边的差值较大的检测出来,然后替换成为255,一般我们将这个常量C设置成为128【255的一半】

复制代码
/**
     * after pixel value - before pixel value + 128
     * 代码引用自 gloomyfish
     * 浮雕效果
     */
    reliefProcess: function(context, canvasData) {
        //caontext 画布对象  document.querySelector().getContext("2d");
        // conavas document.querySelector().getContext("2d").getImageData();
        console.log("Canvas Filter - relief process");
        var tempCanvasData = this.copyImageData(context, canvasData);
        for ( var x = 0; x < tempCanvasData.width-1; x++)
        {
            for ( var y = 0; y < tempCanvasData.height-1; y++)
            {

                // Index of the pixel in the array    
                var idx = (x + y * tempCanvasData.width) * 4;
                var bidx = ((x-1) + y * tempCanvasData.width) * 4;
                var aidx = ((x+1) + y * tempCanvasData.width) * 4;

                // calculate new RGB value
                var nr = tempCanvasData.data[aidx + 0] - tempCanvasData.data[bidx + 0] + 128;
                var ng = tempCanvasData.data[aidx + 1] - tempCanvasData.data[bidx + 1] + 128;
                var nb = tempCanvasData.data[aidx + 2] - tempCanvasData.data[bidx + 2] + 128;
                nr = (nr < 0) ? 0 : ((nr >255) ? 255 : nr);
                ng = (ng < 0) ? 0 : ((ng >255) ? 255 : ng);
                nb = (nb < 0) ? 0 : ((nb >255) ? 255 : nb);

                // assign new pixel value    
                canvasData.data[idx + 0] = nr; // Red channel    
                canvasData.data[idx + 1] = ng; // Green channel    
                canvasData.data[idx + 2] = nb; // Blue channel    
                canvasData.data[idx + 3] = 255; // Alpha channel    
            }
        }
    },
复制代码

 

运行的图像如下:

 cavas的使用汇总[通俗易懂]  

 其中常量的数值越大,浮雕的颜色越浅,反之加深。我们把它设置到50看下效果:

cavas的使用汇总[通俗易懂]

 刻雕效果与浮雕效果基本一样,就是要调整公式里面的Xa和Xb的位置,调整如下:

cavas的使用汇总[通俗易懂]

 四、小结

由于canvas涉及到的知识点比较的深奥,所以里面有很多的内容没法再这里一一的进行说明,这一篇文章也就是对于canvas实际应用的一个简单的说明,在图形学方面,磨皮处理和高通滤波,低通滤波等等方面的处理还没有实现,在一些粒子化,动画,碰撞方面也不能一一道来,深表遗憾

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/166395.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java 图片识别 tess4j_JAVA使用Tess4J进行ocr识别

    java 图片识别 tess4j_JAVA使用Tess4J进行ocr识别Tess4J是对TesseractOCRAPI.的JavaJNA封装。使java能够通过调用Tess4J的API来使用TesseractOCR。支持的格式:TIFF,JPEG,GIF,PNG,BMP,JPEG,andPDFTesseract的github地址:https://github.com/tesseract-ocr/tesseractTess4J的github地址:https…

  • python表白代码大全简单-python表白代码

    python表白代码大全简单-python表白代码广告关闭腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元!作者|马超编辑|jane来源|csdn博客【导语】转眼又到了咱们中国传统的情人节七夕了,今天笔者就带大家来领略一下用python表白的方式。让程序员的恋人们感受一下it人的浪漫。一、词云制作首先咱们可以用之前介绍过的wordcould包制作词云。wordc…

  • ESP32开发之旅——RC522模块的使用

    ESP32开发之旅——RC522模块的使用ESP32开发之旅——RC522模块的使用前言在本文中,您将学会如何使用ESP32连接RFID模块RC522,本文提供了简单的示例供学习参考。需要注意的是,本文中的ESP32是使用MicroPython进行开发的,(同时ESP8266也可按照本文进行开发)。本文中出现的代码是从GitHub开源库中搬运而来,GitHub链接已放在文尾。RFID-RC522模块的简单介绍​ 射频识别RFID(RadioFrequencyIdentification)是一种无线数据传输系统,用于在标签和读取

  • Threading(in thread main)

    PainlessThreadingThisarticlediscussesthethreadingmodelusedbyAndroidapplicationsandhowapplicationscanensurebestUIperformancebyspawningworkerthreadstohandlelong-runningoperat

  • SPPNet网络模型[通俗易懂]

    SPPNet网络模型[通俗易懂]上篇文章详细阐述了R-CNN网络模型,本篇本章本来准备阐述Fast-RCNN模型的,介于SPP-Net模型有许多技巧性的技术可以在不同模型上使用,所以本篇详细分析下SPP-NetSPPNet论文:https://arxiv.org/abs/1406.4729SPPNet论文翻译:https://blog.csdn.net/mengduan…

  • linux 虚拟网络_macvlan原理

    linux 虚拟网络_macvlan原理      macvlan是Linux操作系统内核提供的网络虚拟化方案之一,更准确的说法是网卡虚拟化方案。它可以为一张物理网卡设置多个mac地址,相当于物理网卡施展了影分身之术,由一个变多个,同时要求物理网卡打开混杂模式。针对每个mac地址,都可以设置IP地址,本来是一块物理网卡连接到交换机,现在是多块虚拟网卡连接到交换机。macvlan应该很简单。1.环境准备         假设有一块物理…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号