Android 高级UI解密 (二) :Paint滤镜 与 颜色过滤(矩阵变换)_android paint模糊滤镜-程序员宅基地

技术标签: Android 学习笔记  矩阵运算  滤镜  android  颜色过滤  Paint使用  Android UI学习  

若是曾经查看过系统UI的源码, 会发现其中使用了一些渲染效果,例如将图片加上黑白、怀旧的效果,生活中常用的逆天美颜相机,其中的原理就是使用了滤镜效果、颜色通道过滤。若还要深究其原理组成,便涉及到了高等数学里的矩阵变换,也就是Android 中的颜色矩阵!此篇文章便来一探究竟如何实现滤镜和其原理组成。

(关于矩阵这一块,无需过度深究数学部分,此处为了充分理解渲染效果,只需了解大概原理,利用其API完成简单滤镜效果。)

其实滤镜效果就是对图像进行一定的过滤加工处理。例如PS软件中常见的滤镜效果:模糊、锐化、素描等等,以上功能便涉及到滤镜效果的矩阵。使用Paint设置滤镜效果,可分为以下两个方面:

  • Alpha滤镜处理
  • 颜色RGB的滤镜处理

以上两个方面正好对应Paint的两个重点API,分别是以下:

  • setMaskFilter(MaskFilter filter) 是基于整个画面来进行过滤。
  • setColorFilter(ColorFilter filter)是对每个像素的颜色进行过滤。

此篇文章分为以上两个方面来详细解析滤镜、颜色过滤的奥秘。


Android 高级UI解密 (一) :实例详解Paint 与 高级渲染



一. Alpha滤镜处理

Alpha就是对透明度的处理,涉及到MaskFilter这个类,它是一个抽象类:

这里写图片描述

MaskFilter是在绘制Alpha通道遮罩之前执行转换的对象的基类。 MaskFilter的子类可以通过Paint的setMaskFilter方法设置到画笔中。 而模糊遮罩滤镜BlurMaskFilter和浮雕遮罩滤镜EmbossMaskFilter是实现MaskFilter的子类。

1. 模糊遮罩滤镜BlurMaskFilter

见名识意,此滤镜类似于一种模糊效果。以构造方法中指定的半径模糊其边缘,另外还可指定模糊的风格,模糊其内部、外部、边框或者本身。

//构造方法
BlurMaskFilter (float radius, BlurMaskFilter.Blur style)

参数说明:

  • radius:模糊区域半径;
  • style:模糊的格式 (BlurMaskFilter.Blur 类型)
    • INNER:模糊内部边框,外部不变;
    • NORMAL:模糊内外边框;
    • OUTER:内部不变,模糊外部;
    • SOLID:在边界内部画实体,模糊外面;

注意:注意以上四种类型的解释差异,模糊内部和模糊内部边框是不同的!

  • 内外部边框相关:INNER只是简单模糊其内部边框,图片外部呈现淡白色;而NORMAL是直接模糊内外边框,图片外部已经呈现图片边缘的背景色;
  • 内外部相关:OUTER效果比较奇葩,图片内部空白,外部模糊成图片边缘的背景色;SOLID则是保持内部实体,外部模糊成图片边缘的背景色。

代码测试后的效果图如下:

这里写图片描述

2. 浮雕遮罩滤镜(EmbossMaskFilter)

EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

参数说明:

  • direction:指定光源方向的3个标量[x,y,z]的数组;
  • ambient:指定环境光量强度[0,1];
  • specular:指定镜面反射系数(例如8);
  • blurRadius:指定模糊半径(例如3);
        mPaint.setMaskFilter(new EmbossMaskFilter(new float[]{
   400,100,100}, 0.5f, 60, 80));
        canvas.drawBitmap(bitmap, 400, 100, mPaint);

这里写图片描述

注意:查看EmbossMaskFilter类的构造方法源码,发现其真正创建对象是调用了native方法,因此这也表明google在android 的graphics包中准备了一系列的滤镜,也需要传入相应的参数,而其中参数的运算是非常复杂的,涉及到矩阵运算

需要强调的是“矩阵运算”并非只是简单的公式计算,试想一块手机屏幕所含的像素点有多少,假设是1080P,若一张图片覆盖整个屏幕,需要处理每一个像素点,工作量是很大的,为了计算效率而采用了native方法,交由它来完成。




二. 颜色RGB的滤镜处理

滤镜的所有处理效果都是通过颜色矩阵的变换实现的,例如生活中常见的美颜相机,它实现的一些特效:高光、复古、黑白等滤镜。那么首先来了解何为矩阵?其中涉及到多阶矩阵,这里以二阶矩阵为例进行讲解。

1. 矩阵简析

(1)定义

这里写图片描述

(2)矩阵乘法

矩阵其实就相当于一个二维数组,而重点则在于矩阵之间的计算,特别是乘法计算与后续滤镜计算有关,乘法运算如下:

这里写图片描述

矩阵的乘法计算步骤如下:

  • 将第一个矩阵A的第一行,与第二个矩阵B的第一列的数字分别相乘,得到的结果相加,最终的值做为结果矩阵的第(1,1)位置的值(即第一行,第一列)。
  • 同样,A矩阵的第一行与B矩阵的第二列的数字分别相乘然后相加,结果做为结果矩阵第(1,2)位置的值(即第一行第二列)。
  • 依次类推。

注意:矩阵A乘以矩阵B和矩阵B乘以矩阵A的结果是不一样的。

示例如下:

这里写图片描述


2. 色彩信息的矩阵表示

鲁迅曾经说过(并没有):矩阵运算对于Android像素处理的意义极大!

以上在重点强调矩阵中的乘法运算后,接下来将解密其奥妙。颜色的组成为ARGB,这里先不讨论Alpha透明度,以RGB为主。举个例子:美颜相机中的图片美白原理就是将红色、绿色、蓝色进行位移,可以获得不同的效果,而其中的计算则可以借助矩阵完成。

(1)四阶表示

ARGB的四阶表达式如下:

这里写图片描述

如果想将色彩(0,255,0,255)更改为半透明时,可以使用下面的的矩阵运算来表示:

这里写图片描述

其实颜色变换就是将矩阵看成一套数学模型,便于计算ARGB值。

(2)五阶矩阵

任何一个颜色都是三色素(红绿蓝)构成的,也就是RGB。例如黄色是由红色和绿色形成。

考虑下面这两个变换需求:

  • 红色分量值更改为原来的2倍;
  • 绿色分量增加100;

若要实现以上变换,四阶矩阵的乘法无法实现。根据以上ARGB四阶矩阵的运算规则,只能进行乘法运算,而无法进行加法运算,因此在四阶色彩变换矩阵上增加一个“哑元坐标”,来实现所列的矩阵运算,也就是“五阶矩阵”。过程如下图:

这里写图片描述

第一个矩阵中前四列中任然代表ARGB,而第五列则是分量值,即绿色需要加的100,200 = 1*100+100


3. 实例

(1)需求

通过矩阵变换讲一个图片、颜色块,过滤掉其中的红色、绿色,只留下蓝色。

(2)代码

查看以下代码,绘制出以下两个图形进行对比:

  • 第一个矩形设置其ARGB颜色,整体偏红色;
  • 重点是第二个矩形的颜色过滤器设置:创建其ColorMatrix 矩形变换对象,其中根据上部分公式讲解,结合过滤红色、绿色的需求。因此第一行第一列为R值为0,第二行第二列为G值为0,第三行第三列为B值为1,第四行第四列为A值为1,最后一列是分量值,皆为0。
        //=====颜色RGB的滤镜处理===

        mPaint.setColor(Color.argb(255,200,100,100));
        canvas.drawRect(200, 200, 400, 400, mPaint);

        canvas.translate(400,0);

        //五阶矩阵,R、G为0,A、B为1,第五列为分量,不需要进行平移为0
        ColorMatrix matrix = new ColorMatrix(new float[]{
            0,0,0,0,0,
            0,0,0,0,0,
            0,0,1,0,0,
            0,0,0,1,0,
        });

        //设置颜色过滤器
        mPaint.setColorFilter(new ColorMatrixColorFilter(matrix));
        canvas.drawRect(200, 200, 400, 400, mPaint);

(3)效果展示

这里写图片描述

根据以上对比图实践成功,将第一个矩形中的颜色(#C86464)过滤,仅留下蓝色(#000064)。若纯色块对比不明显,难以理解“过滤”的概念,直接使用图片对比,将以上代码中的drawRect改成drawBitmap即可,效果如下:

这里写图片描述

注意:其滤镜的原理还是在于设置的颜色过滤器——矩阵变换,同理可只过滤掉红色、绿色、蓝色或任意组合,都可由矩阵变换完成。其中不仅可以修改ARGB值(乘法),同样可以修改五阶矩阵中代表分量值的第五列(加法),不同的修改方式可以形成各式滤镜效果。例如美图秀秀中的各种滤镜其原理是如此,内部包含大量的滤镜模板(库)。


4. 实践滤镜效果——色彩运算

以上简单的举个例子实践了矩阵变换,下面来总结归纳其矩阵运算,无非是以下两种:

  • 色彩的平移运算(加法运算)
  • 色彩的缩放运算(乘法运算)

以下代码实践5种滤镜效果来熟悉运用矩阵运算。

(1)反相效果 —— 曝光

常见的照相机中的曝光也就是矩阵运算中的反向,即设原先的ARGB值为100,200,250,用最大值255减去原来的值,结果为155,55,5,就是“曝光”。

矩阵运算解析:其余代码同上个代码示例相同,这里主要是矩阵运算方面的变化:反向效果涉及到用255减去原值,因此直接结合乘法与加法(分量值),可实现该结果!

代码示例如下:

        //曝光效果
        ColorMatrix matrix = new ColorMatrix(new float[]{
            -1,0,0,0,255,
            0,-1,0,0,255,
            0,0,-1,0,255,
            0,0,0,1,0,
        });

图片展示效果如下:

这里写图片描述

(2)美白效果 —– 颜色增强

矩阵运算解析:首先需要知道1f是图像原色,即不改变图像滤镜。若要增强颜色达到一种美白的效果,只需要将RGB值稍加增大即可。

代码如下:

        //美白效果
        ColorMatrix matrix = new ColorMatrix(new float[]{
            1.2f,0,0,0,0,
            0,1.2f,0,0,0,
            0,0,1.2f,0,0,
            0,0,0,1.2f,0,
        });

图片展示效果如下:

这里写图片描述

(3)黑白效果

去色原理:只要把RGB三通道的色彩信息设置成一样,即R=G=B,那么图像就变成了灰色,并且为了保证图像亮度不变,同一个通道中的 R+G+B=1。

例如 0.213+0.715+0.072 = 1,三个数字是根据色彩光波频率及色彩心理学计算出来的。(人对色彩的感知是融合色彩显示和视觉心理成分的,例如你盯着一个纯色快看一段时间,再看向别的事物,此时你看的事物都是自带滤镜的)

矩阵运算解析:根据以上三个值设置RGB即可得到黑白图像的效果,但是需要将五阶矩阵中代表RGB的前四阶中代表各列中每一行的值都设置,A无需考虑,最后以列分量也无需考虑。

代码如下:

        //黑白图片
        ColorMatrix matrix = new ColorMatrix(new float[]{
                0.213f, 0.715f,0.072f,0,0,
                0.213f, 0.715f,0.072f,0,0,
                0.213f, 0.715f,0.072f,0,0,
                0,      0,      0,    1f,0,
        });

图片展示效果如下:

这里写图片描述

(4)色彩反射效果

何为反射效果?例如将图像中红色的成分替换成绿色的成分,绿色的成分替换成红色的。

        //原始效果
        ColorMatrix matrix = new ColorMatrix(new float[]{
            1f,0,0,0,0,
            0,1f,0,0,0,
            0,0,1f,0,0,
            0,0,0,1f,0,
        });

矩阵运算解析:以上是图像原始效果,即ARGB皆为1F,即使设置了此颜色过滤,图像并无任何改变。与此对比,要实现色彩反射效果,比如红色和绿色交换—-把第一行和第二行交换即可。

代码如下:

        //发色效果(比如红色和绿色交换----把第一行和第二行交换)
        ColorMatrix matrix = new ColorMatrix(new float[]{
            0,1f,0,0,0,
            1f,0,0,0,0,
            0,0,1f,0,0,
            0,0,0,1f,0,
        });

图片展示效果如下:

这里写图片描述

(5)复古效果

矩阵运算解析:这是美颜相机中常见的一款滤镜形式,矩阵中有特定的算法模板。

代码如下:

        //复古风格
        ColorMatrix matrix = new ColorMatrix(new float[]{
                1/2f,1/2f,1/2f,0,0,
                1/3f,1/3f,1/3f,0,0,
                1/4f,1/4f,1/4f,0,0,
                0,0,0,1f,0,
            });

图片展示效果如下:

这里写图片描述




三. ColorMatrix 相关详解

上一点讲解了多个有关矩阵变换的例子,对实践矩阵运算和其产生的效果稍有理解,如果涉及到美容相机或者图像处理的一些效果需求,绝大可能会用到矩阵运算,而矩阵运算肯定涉及到ColorMatrix,此部分内容来详细解析ColorMatrix

这里写图片描述

ColorMatrix就是4x5矩阵,用于转换位图的RGB颜色和Alpha分量。 该矩阵可以作为单个数组传递,并按以下方式处理:

  [ a, b, c, d, e,
    f, g, h, i, j,
    k, l, m, n, o,
    p, q, r, s, t ]

当应用于颜色[R,G,B,A]时,每个值的范围是[0, 255],生成的颜色计算如下:

   R’ = a*R + b*G + c*B + d*A + e;
   G’ = f*R + g*G + h*B + i*A + j;
   B’ = k*R + l*G + m*B + n*A + o;
   A’ = p*R + q*G + r*B + s*A + t;

1、构造方法

(1)用指定的值数组创建一个新的Colormatrix

        ColorMatrix matrix = new ColorMatrix(new float[]{});

代码示例:

ColorMatrix matrix = new ColorMatrix(new float[]{
                1.2f,0,0,0,0,
                0,1.2f,0,0,0,
                0,0,1.2f,0,0,
                0,0,0,1.2f,0,
        });

(2)创建一个新的Colormatrix,后续设值

        ColorMatrix matrix = new ColorMatrix();
        float[] scr = {
   ...};
        matrix.set(src)

2.设置色彩的缩放函数(矩阵的乘法运算)

setScale(float rScale, float gScale, float bScale, float aScale)

API作用:设置此颜色矩阵按指定的值进行缩放。
参数:分别是设置R、G、B、A相乘的值。

注意:在上一部分的第四点中已经介绍过矩阵变换中两种重要运算 —— 乘法和加法,并且在以上示例中都是直接修改 4*5 数组矩阵。Colormatrix提供的此API可以轻易设置R、G、B、A需要相乘的值。另外追踪其源码实现也很简单,就是根据参数设置值与数组中对应的R、G、B、A相乘。


3.设置饱和度(矩阵的加法运算)

setSaturation(float sat)

API作用:设置矩阵以影响颜色的饱和度。
参数: sat参数指映射到灰色的值。 1代表原色,0代表灰色,>1则增加饱和度。

API源码

    public void setSaturation(float sat) {
        reset();
        float[] m = mArray;

        final float invSat = 1 - sat;
        final float R = 0.213f * invSat;
        final float G = 0.715f * invSat;
        final float B = 0.072f * invSat;

        m[0] = R + sat; m[1] = G;       m[2] = B;
        m[5] = R;       m[6] = G + sat; m[7] = B;
        m[10] = R;      m[11] = G;      m[12] = B + sat;
    }

源码剖析

有详细查看上一部分内容的读者,你会发现源码中这个三个特殊值很熟悉,它就是在讲解滤镜中黑白效果中有提到的去色原理:R+G+B=1从而图片呈现灰色,同时考虑到色彩光波频率及色彩心理学,计算得出最佳值RGB最佳值:0.213+0.715+0.072 = 1。因此在此基础之上,根据参数设置的值来修改RGB值,达到图像饱和度变化!

实例

下面实现一个简单的demo,在onDraw方法中设置图像的颜色过滤器,设置饱和度为0,在onTouchEvent方法中监听点击处理,每次触控其饱和度以0.3f 增加,查看图像变化效果:

(代码文末提供,在此不赘述)

这里写图片描述

效果分析

查看以上效果符合预期情况,最初设置参数为0,因此图像呈现出灰色,随着不断点击,饱和度依次增加,即RGB值逐渐增加,颜色恢复成原色,接着点击,参数值大于1,图像明显过饱和。


4.色彩旋转函数

setRotate(int axis, float degrees)

API作用:通过指定的值设置颜色轴上的旋转。
参数: axis代表旋转轴,0红色轴,1绿色,2蓝色;degrees代表旋转的度数。

这里写图片描述

注意: 类似于上图中的3D效果,例如这里指定围绕B轴选装,则B值不变,R、G值会随之改变,而且一圈360度旋转完会再次恢复到原始颜色图像。

实例

下面实现一个简单的demo,在onDraw方法中设置图像的颜色过滤器,设置围绕R轴旋转,在onTouchEvent方法中监听点击处理,每次触控其旋转度数以20f增加,查看图像变化效果:

(代码文末提供,在此不赘述)

这里写图片描述

效果分析

查看以上效果,根据设置是围绕R轴旋转,随着度数增加,图像渐渐呈现红色,最终又慢慢恢复成图像原色。既然将此颜色过滤器指定围绕R轴,随着旋转角度增加,达到某一个临界点,图像会逐渐过滤掉所有颜色,只剩下红色。继续增加,颜色接着改变,直至旋转到360度恢复成原图像。


5. ColorFilter的子类

这里写图片描述

ColorFilter类:一个颜色过滤器可以和Paint一起使用来修改用这个颜料绘制的每个像素的颜色。从它的名字也可知,为绘制设置颜色过滤。颜色过滤就是为绘制的内容设置统一的过滤规则。

Paint.setColorFilter(ColorFilter filter)

一般是通过Paint画笔设置其颜色过滤器,由于ColorFilter是抽象类,使用的是它的三个子类,如下:

(1)ColorMatrixColorFilter 色彩矩阵的颜色顾虑器

类作用:通过4x5彩色矩阵转换颜色的彩色滤镜。 这个滤镜可以用来改变像素的饱和度,从YUV转换到RGB等。

//构造函数
new ColorMatrixColorFilter(ColorMatrix matrix);

构造方法参数:就是**ColorMatrix**4x5矩阵,用于转换位图的RGB颜色和Alpha分量。

注意:本篇文章第二大部分颜色RGB的滤镜处理,使用的都是ColorMatrixColorFilter 色彩矩阵的颜色顾虑器,在此无需赘述。

(2) LightingColorFilter 光照颜色过滤器(过滤颜色和增强色彩)

类作用:可用于模拟简单照明效果的滤色器。 一个LightingColorFilter由两个参数定义,一个用于将源颜色(称为colorMultiply)和一个用于添加到源颜色(称为colorAdd)的颜色相乘。 这个彩色滤光片保持不变的alpha通道。

给定源颜色RGB,由此得出R’G’B’颜色:

 R' = R * colorMultiply.R + colorAdd.R
 G' = G * colorMultiply.G + colorAdd.G
 B' = B * colorMultiply.B + colorAdd.B
//构造函数
new LightingColorFilter(int mul, int add);

构造方法参数: mul是与源RGB相乘的值;add是与源RGB相加的分量值。

注意:此方法就是结合了矩阵运算中的乘法和加法,更加简化。需要注意的是参数类型虽为int值,但规定为颜色值,即16进制的值,例如0x00ff00,说白了就是范围 [0,255]区间的颜色值。

实例

这里做一个简单的测试,设置LightingColorFilter 光照颜色过滤器的两个参数分别为0x00ff00,0x000000。0x00ff00就是一个绿色值(原谅色~),会与RGB源值相乘,而这里相加的值设置为0,不做修改。因此设置该光照颜色过滤器后,图像整体应该呈现出绿色。

        ......
        mPaint.setColorFilter(new LightingColorFilter(0x00ff00, 0x000000));
        canvas.drawBitmap(bitmap, null, new RectF(200, 200, 400, 400*bitmap.getHeight()/bitmap.getWidth()), mPaint);

效果如下:

这里写图片描述

效果分析

图片效果与理想效果相符,因此根据此API可轻易完成矩阵变换中的乘法和加法运算,实现需求效果。

(3) PorterDuffColorFilter 图形混合滤镜(图形学理论)

类作用:一种彩色滤光片,可用于使用单色和特定的Porter-Duff复合模式为源像素着色。 就是使用一个指定的颜色和一种指定的 PorterDuff.Mode 来与绘制对象进行合成。

//构造函数
new PorterDuffColorFilter(int color, PorterDuff.Mode mode); 

构造方法参数: color 参数是指定的颜色;mode 参数是指定的 Mode,即PorterDuff.Mode

注意: PorterDuffColorFilterComposeShader两者都使用到了PorterDuff.Mode,其中一个是颜色过滤器,一个是着色器,而且PorterDuffColorFilter颜色过滤器只能指定一种颜色作为源,而不是一个 Bitmap。




文章小结

此篇文章的主要是研究Paint的两个重点API:从Alpha滤镜处理、颜色RGB的滤镜处理两个方面拓展开,其中涉及到了高数知识——矩阵运算,此篇为了研究颜色过滤原理稍作介绍,并实践展示了几个滤镜效果,学会API实际运用。

此篇文章是有关于有关Paint的高级使用,结合上一篇Paint的基本使用,Paint相关知识重点暂时介绍到这里,下一篇文章将开始归纳Canvas画布相关内容。


(代码整理中,后续会提供)

若有错误,欢迎指教~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ITermeng/article/details/78636132

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签