精华内容
下载资源
问答
  • 5 >> a3=A(7) %因此在mxn的矩阵中用单下标取值时,A(i,j) = A((j-1)*m+i) a3 = 10 >> a4=A(1,:) %获取矩阵第一行,所有的类元素,即获取矩阵第一行元素 a4 = 1 2 3 4 >> a5=A(:,3) %获取矩阵第三列所有行元素,即...

    一维数组(创建,赋值,取值,分割取值,四则运算等操作)

    创建一维数组

    >> A=[] %创建空的数组

    >> B=[1 2 3 4 5] %两种创建行向量,数组的方式

    >> C=[1,2,3,4,5]

    >> D=[1;2;3;4;5] %创建列向量,数组的方式

    结果:

    A =

    []

    B =

    1 2 3 4 5

    C =

    1 2 3 4 5

    D =

    1

    2

    3

    4

    5

    用冒号创建递增,递减数组

    >> A=2:6 %创建一维数组,行向量,从2 到6, 默认每次递增1

    >> B=2.5:2:10.9 %从2.5 到10.9 指定每次递增2

    >> C=8:-2:1 % 从8 到1, 指定每次递减-2

    结果

    A =

    2 3 4 5 6

    B =

    2.5000 4.5000 6.5000 8.5000 10.5000

    C =

    8 6 4 2

    用matlab的函数linspace() 建立一维数组,和冒号功能类似

    >> A=linspace(0,10,20) % 从0 到10 ,建立20个元素的等差数列

    >> B=linspace(2,7,2) %从2到7 ,建立2个元素的等差数列

    >> C=linspace(2,7,1) %从2到7 ,建立1个元素的等差数列

    结果:

    A =

    1 至 12 列

    0 0.5263 1.0526 1.5789 2.1053 2.6316 3.1579 3.6842 4.2105 4.7368 5.2632 5.7895

    13 至 20 列

    6.3158 6.8421 7.3684 7.8947 8.4211 8.9474 9.4737 10.0000

    B =

    2 7

    C =

    7

    一维数组的取值,赋值,分割取值(取部分值)

    >> A=[1,2,3,4,5]

    >> b1=A(3) %取一个元素,取第3个元素,结果是3

    >> b2=A([2,4]) %取多个不连续的元素,取第2 和第4 个元素,结果是2,4

    >> b3=A(2:4) %取数组A的 第2 到第4 的元素,结果是2,3,4

    >> b4=A(3:end) %取数组第3个元素到最后一个元素,结果3,4,5

    >> b5=(3:-1:1) % 反取,从第3个元素到第1个元素,3,2,1

    >> b6=A(end:-1:1)

    二维数组的创建,数据获取

    >> A=[1 2 3; 4 5 6] %创建2行3列 数组

    A =

    1 2 3

    4 5 6

    >> a1=A(1,3) %获取第一行第3个元素

    a1 =

    3

    >> a2=A(:,2) %获取数组A 的第2列元素,结果是一个列向量

    a2 =

    2

    5

    >> a3=A(1,:) %获取数组A的第一行元素,结果是一个行向量

    a3 =

    1 2 3

    数组的加减乘除四则运算

    >> A=[1,2,3,4,5]

    >> B=[0 1 3 5 2]

    >> C=A-B %每个元素相减

    C =

    1 1 0 -1 3

    >> D=A+B %每个元素相加

    D =

    1 3 6 9 7

    >> E=A.*B %数组的点乘,

    E =

    0 2 9 20 10

    >> F=A*3 %数组的数乘

    F =

    3 6 9 12 15

    >> G=A./B %数组左除数组,如果分子为0,则结果为无穷大(Inf)

    G =

    Inf 2.0000 1.0000 0.8000 2.5000

    >> H=A./3 %数组左除常数

    H =

    0.3333 0.6667 1.0000 1.3333 1.6667

    >> J=A.\B %数组右除数组, 即数组B 除数组A

    J =

    0 0.5000 1.0000 1.2500 0.4000

    >> L=A.^B %数组的乘方

    L =

    1 2 27 1024 25

    >> N=dot(A,B) %数组的点积,即两个数组相应位置相乘,再累加

    N =

    41

    数组的排序

    >> A=[10 9 6 1 5]

    >> B=sort(A) %默认是升序排序

    B =

    1 5 6 9 10

    >> [C,I]=sort(A,'ascend') %对数组A进行升序排序,C 返回排序后结果,I 返回排序后元素在元素组的位置

    C =

    1 5 6 9 10

    I =

    4 5 3 2 1

    >> D=sort(A,'descend') %降序排列

    D =

    10 9 6 5 1

    矩阵的操作

    矩阵的创建,取值

    >> A=[1:4;5:8;9:12;13:16] %创建多维矩阵

    A =

    1 2 3 4

    5 6 7 8

    9 10 11 12

    13 14 15 16

    >> a1=A(2,3) %获取矩阵中第2行第3列的一个元素

    a1 =

    7

    >> a2=A(2) %在matlab中,矩阵元素按照列进行存储,先存第一列,再存第二列,依次类推

    a2 =

    5

    >> a3=A(7) %因此在mxn的矩阵中用单下标取值时,A(i,j) = A((j-1)*m+i)

    a3 =

    10

    >> a4=A(1,:) %获取矩阵第一行,所有的类元素,即获取矩阵第一行元素

    a4 =

    1 2 3 4

    >> a5=A(:,3) %获取矩阵第三列所有行元素,即获取矩阵第3列元素

    a5 =

    3

    7

    11

    15

    >> a6=A(1:2,1:2) %获取矩阵第一二行,第一二列元素,即获取矩阵的子矩阵

    a6 =

    1 2

    5 6

    矩阵操作

    矩阵转置

    >> A=[1:4;5:8;9:12;13:16]

    A =

    1 2 3 4

    5 6 7 8

    9 10 11 12

    13 14 15 16

    >> B=A'

    B =

    1 5 9 13

    2 6 10 14

    3 7 11 15

    4 8 12 16

    >> C=transpose(A)

    C =

    1 5 9 13

    2 6 10 14

    3 7 11 15

    4 8 12 16

    矩阵求逆

    >> A=magic(3)

    A =

    8 1 6

    3 5 7

    4 9 2

    >> B=inv(A)

    B =

    0.1472 -0.1444 0.0639

    -0.0611 0.0222 0.1056

    -0.0194 0.1889 -0.1028

    矩阵基础数值运算

    加减法

    >> A=[1:4;5:8]

    A =

    1 2 3 4

    5 6 7 8

    >> B=[2 3 4 5;6 7 4 5]

    B =

    2 3 4 5

    6 7 4 5

    >> C=A-B

    C =

    -1 -1 -1 -1

    -1 -1 3 3

    >> D=A+100

    D =

    101 102 103 104

    105 106 107 108

    乘法

    >> A=[1:4;5:8]

    A =

    1 2 3 4

    5 6 7 8

    >> B=[2 3;1 3; 6 7; 4 5]

    B =

    2 3

    1 3

    6 7

    4 5

    >> C=A*B %矩阵相乘,

    C =

    38 50

    90 122

    >> D=A.*B' %矩阵点乘,相应位置元素相乘

    D =

    2 2 18 16

    15 18 49 40

    除法

    >> A=[21 2 3; 7 3 1; 9 4 2]

    A =

    21 2 3

    7 3 1

    9 4 2

    >> B=[3 5 7; 2 12 4; 2 7 4]

    B =

    3 5 7

    2 12 4

    2 7 4

    >> C=B/A %矩阵右除,常用

    C =

    -0.3429 -10.3714 9.2000

    -1.4857 -1.9429 5.2000

    -0.7714 -4.0857 5.2000

    >> D=B*inv(A)

    D =

    -0.3429 -10.3714 9.2000

    -1.4857 -1.9429 5.2000

    -0.7714 -4.0857 5.2000

    >> E=A\B %矩阵左除, 结果和右除不一样,不常用

    E =

    0.2286 1.6286 0.5143

    0.4286 4.4286 0.7143

    -0.8857 -12.6857 -1.7429

    特殊矩阵生成

    全零矩阵

    >> A=zeros(2,3) %生成2行3列全0矩阵

    A =

    0 0 0

    0 0 0

    全1矩阵

    >> B=ones(3,2)

    B =

    1 1

    1 1

    1 1

    单位矩阵

    >> C=eye(3)

    C =

    1 0 0

    0 1 0

    0 0 1

    >> D=eye(4,3)

    D =

    1 0 0

    0 1 0

    0 0 1

    0 0 0

    魔方矩阵

    矩阵中每行,每列及两条对角线上的元素和都相等

    >> A=magic(3)

    A =

    8 1 6

    3 5 7

    4 9 2

    0~1间均匀分布的随机矩阵

    >> A=rand(2,3)

    A =

    0.2151 0.1130 0.2219

    0.1413 0.2247 0.2220

    标准正太分布随机矩阵

    生成均值为0,方差为1 的标准正太分布

    >> B=randn(2,3)

    B =

    -0.0742 0.9599 1.1348

    -0.7403 0.3222 0.4410

    matlab与概率统计

    均匀分布随机数的产生

    连续型均匀分布的随机数据

    >> r=unifrnd(1,3) %返回区间[1,3]的连续型均匀分布随机数

    r =

    2.4042

    >> R1=unifrnd(1,3,4,4) %返回区间[1,3]的连续型均匀分布随机数矩阵4X4

    R1 =

    2.7087 1.5790 2.2197 2.4457

    1.2678 2.3417 2.2246 2.6568

    1.2570 1.4633 2.9900 1.7311

    1.9149 1.4180 2.9795 1.2921

    离散型均匀分布

    >> r2=unidrnd(10) %产生离散型均匀分布随机数据

    r2 =

    8

    >> R2=unidrnd(8,4,4) %产生离散型均匀分布随机数据矩阵

    R2 =

    6 2 4 1

    8 6 5 7

    7 3 8 3

    8 5 4 4

    正太分布随机数据产生

    >> r=normrnd(0,1) %产生服从均值为0,标准差为1 的正太分布随机数

    r =

    0.5694

    >> r=normrnd(0,1,3,5) %产生服从均值为0,标准差为1 的正太分布随机数矩阵

    r =

    0.6118 -0.5573 0.9197 -1.0885 -1.5243

    -0.4902 0.8021 -0.5572 0.6006 -0.3111

    -1.7272 1.5039 0.3487 0.4130 1.6368

    均匀分布概率密度函数

    >> clear all

    >> n=20;

    >> x=1:n;

    >> y=unidpdf(x,n);

    >> figure;

    >> plot(x,y,'ro');

    >> title('均匀分布(离散)');

    %连续型均匀分布

    >> clear all

    >> x=-5:0.1:10;

    >> y=unifpdf(x,0,5);

    >> plot(x,y,'r')

    正态分布概率密度函数

    >> x=-8:0.5:8;

    >> y1=normpdf(x,0,1); %标准正太分布

    >> y2=normpdf(x,2,2); %非标准正态分布

    >> plot(x,y1,x,y2,':')

    >> x1=-4:0.5:8;

    >> y3=normpdf(x1,2,1); %标准差越小,曲线就越都

    >> y4=normpdf(x1,2,2);

    >> y5=normpdf(x1,2,3);

    >> plot(x1,y3,'r-',x1,y4,'b:',x1,y5,'k--')

    >> legend('SIGMA=1','SIGAM=2','SIGMA=3');

    >> x1=-4:0.5:8;

    >> y6=normpdf(x1,0,1.5); %标准差越小,曲线就越都

    >> y7=normpdf(x1,2,1.5);

    >> y8=normpdf(x1,4,1.5);

    >> plot(x1,y6,'r-',x1,y7,'b:',x1,y8,'k--')

    >> legend('MU=0','MU=2','MU=4');

    展开全文
  • R语言lattice包的levelplot函数在绘制相关系数矩阵图时,如何将右侧的图例范围控制在指定范围,如0-1之间,即统一多张图的绘图方式,如0.8在所有图中都橙色表示,而不是不同图中颜色不同。 ![图片说明]...
  • MATLAB拟合出的代码绘图合成器 介绍 一个Python包,用于为比较案例研究实现综合控制方法。 合成控制方法已用于研究评估单个单元暴露于干预措施时的效果。 Synth R软件包的维护者Jens Hainmueller在这里将这种方法...
  • MATLAB拟合出的代码绘图代谢表型研究的功效分析 功率分析脚本 到目前为止,大多数都是MATLAB代码,但是python 3.5版本将在不久的将来可用... 主要文件和说明: 教程:脚本以及有关如何运行代码的示例 Pcalc_2Group...
  • 用矩阵X、Y分别存储每一个小矩形顶点的x坐标与y坐标,矩阵X、Y就是该矩形区域的xy平面网格坐标矩阵。 例如,在X-Y坐标平面生成一个由(2,6),(3,8)围成的网格坐标。 在MATLAB中,产生平面区域内的网格坐标矩阵...

    0 前言

    本文是科学计算与MATLAB语言的专题四的第6、7小节总结笔记,并结合了自己一点的理解,看完本文,可以轻松借助MATLAB画出更加漂亮的图形。在本文的第二部分,也总结了交互式绘图工具的用法。

    1 图形修饰处理

    如同做好了一个非常棒的产品,怎么能够推销出去呢,让顾客看的更加直观呢,答案就是艺术加工。

    1.1 视点处理

    1.视点处理
    方位角(Az):视点与原点连线在xy平面上的投影与y轴负方向形成的角度,正值表示逆时针,负值表示顺时针。
    仰角(El):视点与原点连线与xy平面的夹角,正值表示视点在xy平面上方,负值表示视点在xy平面下方。
    视图
    这个图我不会画,直接找的官网的图。如果那个大佬知道怎么花的,告诉我哈。 😄
    view函数的基本用法
    view(az,el)
    其中
    az为方位角,el为仰角。
    系统默认的视点定义为方位角-37.5°,仰角30°。
    例1 绘制函数z=(x1)2+(y2)21z=(x−1)^2+(y−2)^2−1曲面,并从不同视点展示曲面。
    plot3.14

    [x,y]=meshgrid(0:0.1:2, 1:0.1:3);
    z=(x-1).^2+(y-2).^2-1;
    subplot(2,2,1); mesh(x,y,z)
    title('方位角=-37.5{\circ},仰角=30{\circ}')
    subplot(2,2,2); mesh(x,y,z)
    view(0,90);title('方位角=0{\circ},仰角=90{\circ}')
    subplot(2,2,3); mesh(x,y,z)
    view(90,0); title('方位角=90{\circ},仰角=0{\circ}')
    subplot(2,2,4); mesh(x,y,z)
    view(-45,-60); title('方位角=-45{\circ},仰角=-60{\circ}')
    

    view函数的其他用法
    view(x,y,z)
    view(2)在二维视图中显示绘图。
    view(3)在三维视图中显示绘图。

    视图 方位角 仰角
    view(2) 90°
    view(3) -37.5° 30°

    1.2 色彩处理

    颜色的向量表示
    向量元素在[0,1]范围内取值,3个元素依次表示红、绿、蓝3种颜色的相对亮度,称为RGB三元组。
    [r g b]
    [001]:蓝色
    [100]:红色
    [010]:绿色
    [111]:白色
    [000]:黑色
    色图(Colormap)
    1色图矩阵
    2指定当前图形使用的色图
    colormap cmapname
    colormap(cmap)
    3创建色图矩阵
    色图矩阵的每一行是RGB三元组。可以自定义色图矩阵,也可以调用MATLAB提供的函数来定义色图矩阵。
    例2 创建一个灰色系列色图矩阵。
    plot3.15

    c = [0, 0.2, 0.4, 0.6, 0.8, 1.0]';
    cmap = [c, c, c];
    surf(peaks)
    colormap(cmap)
    

    cmap=gray(6);
    surf(peaks)
    colormap(cmap)
    

    4三维图形表面的着色
    可以用shading函数来改变着色方式

    命令 使用说明
    shading flat 每个网格片用同一个颜色进行着色,且网格线也用相应的颜色
    shading faceted 每个网格片用其高度对应的颜色进行着色,网格线是黑色。这是默认着色方式。
    shading interp 网格片内采用颜色插值处理。

    例3 使用同一色图,以不同着色方式绘制圆锥体。
    plot3.16

    [x,y,z]= cylinder(pi:-pi/5:0,10);
    colormap(lines);
    subplot(1,3,1);
    surf(x,y,z); shading flat
    subplot(1,3,2);
    surf(x,y,z); shading interp
    subplot(1,3,3);
    surf(x,y,z);
    

    1.3 图形的裁剪处理

    将图形中需要裁剪部分对应的函数值设置成NaN,这样在绘制图形时,函数值为NaN的部分将不显示出来,从而达到对图形进行裁剪的目的。
    例4 绘制3/4圆。
    plot3.17

    t = linspace(0,2*pi,100);
    x = sin(t);
    y = cos(t);
    p = y > 0.5;
    y(p)= NaN;
    plot(x,y)
    axis([-1.1,1.1,-1.1,1.1])
    axis square
    grid on
    

    例5 绘制3/4球面。
    plot3.18

    [X, Y, Z] = sphere(60);
    p = Z>0.5;
    Z(p) = NaN;
    surf(X, Y, Z)
    axis([-1, 1, -1, 1, -1, 1])
    axis equal
    view(-45, 20)
    

    2 交互式绘图工具

    2.1 “绘图”选项卡

    绘图选项卡
    “绘图”选项卡的工具条提供了绘制图形的基本命令。
    “所选内容”命令组:用于显示已选中用于绘图的变量;
    “绘图”命令组:提供了绘制各种图形的命令;
    “选项”命令组:用于设置绘图时是否新建图形窗口。
    通过下面命令,生成一些变量。

    x=linspace(0,2*pi,100);
    y=sin(x);
    y1=sin(x);
    y2=sin(0.5*x);
    y3=sin(2*x);
    [u,v]=meshgrid(0:0.1:2,1:0.1:3);
    h=(u-1).^2+(v-2).^2-1;
    [X,Y,Z]= cylinder(0:0.2:2,30);
    

    可以在工作区查看生成的变量。
    变量
    通过选中其中的变量,点击绘图命令组的按钮即可绘图。
    切换变量坐标顺序
    先选中的是X轴数据,后选中的是Y轴数据。通过点击切换按钮,可以切换顺序。

    2.2 图形窗口绘图工具

    显示绘图工具
    可以通过“显示绘图工具和停靠图形”按钮调出图形窗口绘图工具。
    显示绘图工具
    也可以在命令行窗口中输入以下命令调出

    plottools
    

    绘图工具的组成
    、绘图浏览器、属性编辑器等。
    在这里插入图片描述
    窗口不一样也不用慌,可以用点击查看调出相关工具,也可以用鼠标调整其大小。
    图形选项板:用于在图形窗口中添加和排列子图,观察和选择绘图数据以及添加图形标注。
    绘图浏览器:以图例的方式列出图形中的元素。
    属性编辑器:用于观测和设置所选对象的名称、颜色、填充方法等参数。不同类型的对象,属性编辑器中的内容不同。

    2.3 图形窗口菜单和工具栏

    工具栏
    窗口
    第一栏 图形文件操作
    第二栏 图形操作
    第三栏 添加颜色栏、图例
    图形窗口菜单
    保存
    图形绘制完成后,可以用“文件”菜单中的“生成代码”命令,将实施在图形上的这些操作命令输出成脚本。也可以用“保存”命令将图形窗口内容保存为fig文件。

    3 结语

    您是否学会了呢?如果本文对您有帮助,可以点个赞哈,如有错误疑问,请您指出哈。

    展开全文
  • MATLAB拟合出的代码绘图机器学习_INM431 内容 第一周笔记 MatLab的主要命令 如果您在MatLab命令终端中的“编辑”之后键入任何内置的MatLab方法,您将获得有关该方法如何工作甚至代码本身的详细信息。 例如,下面的...
  • MATLAB拟合出的代码绘图BeeNestABM BeeNestABM:基于开源代理的大WaSP在巢中的时空分布模型 代码: 纸: 图1:BeeNestABM示例结果快照:蜜蜂(蓝点),女王(大红色圆圈)和巢结构(黄色,白色和灰色圆圈)的位置...
  • 本文介绍Android绘图相关知识点,包括: 1. 2D绘图-Canvas、paint ... 如何用颜色矩阵处理bitmap 3. 如何用像素点、颜色块处理bitmap 4. 如何使用变换矩阵处理图片 5. 如何使用画笔做特效处理...

    转载请注明链接:http://blog.csdn.net/feather_wch/article/details/79210109

    本文介绍Android绘图相关知识点,包括:
    1. 2D绘图-Canvas、paint
    2. 如何用颜色矩阵处理bitmap
    3. 如何用像素点、颜色块处理bitmap
    4. 如何使用变换矩阵处理图片
    5. 如何使用画笔做特效处理

    Android绘图机制(22题)

    版本:2018.1.30-2

    所有知识点参考总结自: http://blog.csdn.net/feather_wch/article/details/78589840

    1、屏幕尺寸信息有哪些?

    1. 屏幕大小指的是屏幕对角线的长度,使用“寸”度量,4.7寸手机、5.5寸手机
    2. PPI:每英寸像素(Pixels Per Inch)又被称为DPI,对角线的像素点数除以屏幕的大小得到的。
    3. dp是独立像素密度: Android用mdpi即密度值为160的屏幕作为标准,在这个屏幕上1px = 1dp。例如100dp的长度,在mdpi中为100px,而在hdpi中为150px。因此dp用于屏幕适配最好。

    2、独立像素密度dp和像素px换算表

    比例换算表 mdpi hdpi xhdpi xxhdpi
    dp 1 1 1 1
    px 1 1.5 2 3

    3、Android如何进行2D绘图

    1. 系统提供Canvas提供绘图方法。还提供了各种绘制图像的API。
    2. Canvas提供各种绘制图像的API:如drawPoint点,drawLine线,矩形,多边形,弧,圆等。
    3. Paint是系统提供的画笔,能提供setAntiAlias()设置锯齿效果,setStyle()设置画笔的风格等等

    4、2D绘图实例:

    public class TwoDActivity extends Activity {
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            /*将自定义控件设为ContentView-用于测试Canvas效果*/
            setContentView(new CustomeView(this));
        }
        /**-----------------------------------------
         *   自定义控件,重写draw方法,用于测试canvas
         * -----------------------------------------*/
        class CustomeView extends View{
            public CustomeView(Context context){
                super(context);
            }
            @Override
            public void draw(Canvas canvas) {
                /*---------------------------------
                *   绘制实心矩形
                * --------------------------------*/
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.FILL); //画笔风格
                paint.setColor(Color.BLACK);      //画笔颜色
                canvas.drawRect(0, 0, 100, 100, paint);//绘制矩形
                /*---------------------------------
                *   绘制空心矩形
                * --------------------------------*/
                paint.setStyle(Paint.Style.STROKE); //画笔风格
                paint.setColor(Color.BLACK);        //画笔颜色
                canvas.drawRect(150, 0, 250, 100, paint);//绘制矩形
                /*-----------------------------------------------------------------
                *    在指定位置绘制文字-以(x,y)起点的水平直线为基准线,绘制直线Text
                * -----------------------------------------------------------------*/
                paint.setStyle(Paint.Style.FILL); //画笔风格
                paint.setTextSize(80);
                paint.setColor(Color.RED);        //画笔颜色
                canvas.drawText("Hello World!", 300, 100, paint);
                super.draw(canvas);
            }
        }
    }

    5、Canvas中的四个重要方法:

    1. Canvas.save():将之前绘制内容都保存起来,接下来的绘制就好像在新的图层进行绘制一样。
    2. Canvas.restore():合并图层操作,将save之后的图像和save之前的图像合并起来。
    3. Canvas.tanslate():平移,将坐标系进行平移,绘制都以之后的坐标系为参照。
    4. Canvas.rotate():旋转,将坐标系进行旋转。避免了复杂运算,化繁为简。

    6、利用Canvas的旋转实现复杂效果:自定义时钟

    private int mCenterX = 550; //自定义圆心X
        private int mCenterY = 800; //自定义圆心Y
        private int mRadius = 500; //圆的半径
        /**-----------------------------------------
         *           自定义钟表
         * -----------------------------------------*/
        class ClockView extends View{
            public ClockView(Context context){
                super(context);
            }
            protected void onDraw(Canvas canvas) {
                //绘制圆形
                Paint paint = new Paint();
                paint.setAntiAlias(true);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5);
                canvas.drawCircle(mCenterX, mCenterY, mRadius, paint);
                /*--------------------------------------------
                *  绘制刻度线: 1. 先在0点位置绘制竖线
                *             2. 将坐标系旋转30度
                *             3. 继续原样绘制竖线
                *             4. 循环绘制,最终绘制出所有刻度线
                * -------------------------------------------*/
                paint = new Paint();
                paint.setStrokeWidth(3);
                for(int i = 0; i < 12; i++){
                    //大刻度线
                    if(i == 0 || i == 3 || i == 6 || i == 9){
                        paint.setColor(Color.RED);
                        paint.setStrokeWidth(5);
                        canvas.drawLine(mCenterX, mCenterY-mRadius, mCenterX, mCenterY-mRadius+60, paint);
                        String strTime = i+"";
                        int textSize = 40;
                        paint.setTextSize(textSize);
                        canvas.drawText(strTime, mCenterX-textSize/3, mCenterY-mRadius+60+textSize, paint);
                    }else{
                        paint.setColor(Color.BLACK);
                        paint.setStrokeWidth(3);
                        canvas.drawLine(mCenterX, mCenterY-mRadius, mCenterX, mCenterY-mRadius+30, paint);
                        int textSize = 20;
                        String strTime = i+"";
                        paint.setTextSize(textSize);
                        canvas.drawText(strTime, mCenterX-textSize/3, mCenterY-mRadius+30+textSize, paint);
                    }
                    //旋转
                    canvas.rotate(30, mCenterX, mCenterY);
                }
                super.onDraw(canvas);
            }
        }

    7、Canvas中的图层概念

    1. saveLayer(),saveLayerAlpha()将一个图层入栈。
    2. restore(), restoreToCount()将一个图层出栈。
    3. 入栈后,所有操作发生在该图层之上。
    4. 出栈后,就会将图像绘制到上层Canvas上。

    8、Bitmap位图是什么

    1. Android中最常用的就是位图Bitmap.
    2. Bitmap包含了点阵和颜色值
    3. 点阵就是包含像素的矩阵。
    4. 颜色值就是ARGB-对应透明度、红色、绿色、蓝色。

    9、图像描述的三个角度

    1. 色调-物体显示的颜色
    2. 饱和度-颜色的纯度。0(灰度)到100%(饱和)来进行描述。
    3. 亮度-颜色相对的明暗程度。
    4. Android封装了一些API来快速调整这些参数,不用计算矩阵值。

    10、ColorMatrix是什么?

    1. Android中的颜色矩阵

    11、实例:改变色光属性(色调、饱和度、亮度)

    public class BitmapActivity extends Activity implements SeekBar.OnSeekBarChangeListener{
      /**==========================
       * 省略seekbar初始化等不重要内容
       *=========================*/
        float mHue = 0; //色调初始值为0, 原图色调
        float mSaturation = 1; //饱和度1,原图饱和度
        float mLum = 1; //亮度1,原图亮度
        //SeekBar的中间值
        int MID_VALUE = 127;
        //SeekBar的最大值
        int MAX_VALUE = 255;
        /**==========================
         * 1. 获取色光属性-色调、饱和度、亮度
         *     初始范围0~255
         *=========================*/
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            switch(seekBar.getId()){
                case R.id.hue_seekbar:
                    mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
                    break;
                case R.id.saturation_seekbar:
                    mSaturation = progress * 1.0F  / MID_VALUE;
                    break;
                case R.id.lum_seekbar:
                    mLum =  progress * 1.0F  / MID_VALUE;
                    break;
                default:break;
            }
            imageView.setImageBitmap(handleImageEffect(mHue, mSaturation, mLum));
        }
        /**----------------------------------------------------
         * 处理图像的色调,饱和度,亮度。
         *   因为Android中不能处理原Bitmap,需要处理Bitmap的副本,
         *   因此使用原Bitmap创建副本,进行处理。
         * ---------------------------------------------------*/
        public Bitmap handleImageEffect(float hue, float saturation, float lum){
            //1. 创建副本Bitmap
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.jide);
            Bitmap bitmap = bmp.copy(Bitmap.Config.ARGB_8888,true);
            //2. 创建画板、画笔
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            /*-----------------------------------
            * 处理色调: setRotate中0,1,2代表R,G,B
            * -----------------------------------*/
            ColorMatrix hueColorMatrix = new ColorMatrix();
            hueColorMatrix.setRotate(0, hue);
            hueColorMatrix.setRotate(1, hue);
            hueColorMatrix.setRotate(2, hue);
            /*-----------------------------------
            *  设置饱和度
            * -----------------------------------*/
            ColorMatrix saColorMatrix = new ColorMatrix();
            saColorMatrix.setSaturation(saturation);
            /*-------------------------------------------
            * 设置亮度:将三原色相同比例混合显示出白色,以此提高亮度
            * ------------------------------------------*/
            ColorMatrix lumColorMatrix = new ColorMatrix();
            lumColorMatrix.setScale(lum, lum, lum, 1);
            /*---------------------------------
            *  将矩阵作用效果混合, 叠加效果。
            * --------------------------------*/
            ColorMatrix colorMatrix = new ColorMatrix();
            colorMatrix.postConcat(hueColorMatrix);
            colorMatrix.postConcat(saColorMatrix);
            colorMatrix.postConcat(lumColorMatrix);
            /*-------------------------
            *  设置矩阵, 进行绘制
            * ------------------------*/
            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            canvas.drawBitmap(bitmap, 0, 0, paint);
            return bitmap;
        }
    }

    12、Android颜色矩阵-ColorMatrix

    1. 使用4X5颜色矩阵进行色彩处理。通过设置具体矩阵某元素来处理色彩。
      2.
    /*--------------------------------------
     *  将矩阵数组4x5(一维)通过ColorMatrix作用到图像上
     *  以此对图片进行色彩处理
     * ------------------------------------*/
    Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);
    //1. 将颜色矩阵设置给ColorMatrix
    ColorMatrix colorMatrix = new ColorMatrix();
    colorMatrix.set(mColorMatrix);
    //2. 用颜色矩阵进行绘制
    Canvas canvas = new Canvas(bmp);
    Paint paint = new Paint();
    paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
    canvas.drawBitmap(bitmap,0, 0, paint);
    //3. 将改变后的Bitmap设置到ImageView上显示
    mImageView.setImageBitmap(bmp);

    13、常用色彩处理矩阵

    1. 有灰度、反转、怀旧等。
      2.反转矩阵(其余不赘述,请查询资料)
    -1 0 0 1
    0 -1 0 1
    0 0 -1 1
    0 0 0 1

    14、像素点处理图片

    1.可以通过改变每个像素点的ARGB值,进行色彩处理。
    2.Bitmap.getPixels(colorArray,省略...)能提取整个图片的像素点,并保存到数组中。
    3.AGBA获取:

    r = Color.red(colorArray);
    g = Color.green(colorArray);
    b = Color.blue(colorArray);
    a = Color.alpha(colorArray);

    4.获取到原ARGB后,通过计算得到新的ARGB。r1 = i* r + j* g + k* b;

    newPix[i] = Color.argb(a, r1, g1, b1);
    bitmap.setPixels(newPix, ...);

    5.使用不同参数,就能达到老照片、浮雕等效果。

    15、矩阵Matrix的作用

    1. 图形变换类似于颜色变换。使用3X3变换矩阵进行变换。可以进行平移变换、缩放变换、旋转变换、错切变换。
    2. 矩阵Matrix能对图片进行平移、缩放、旋转、错切变换。
            static float data = 10f; //自定义的数据
            Canvas canvas = new Canvas();
            /*------------------------------------
            * 使用矩阵处理图片
            * -----------------------------------*/
            float[] mImageMatrix = new float[9];
            Matrix matrix = new Matrix();
            matrix.setValues(mImageMatrix);//转为矩阵
            canvas.drawBitmap(bitmap, matrix, null);
            //set会覆盖整个矩阵
            matrix.setRotate(data); //旋转
            matrix.setTranslate(data, data);//平移
            matrix.setScale(data, data); // 缩放
            matrix.setSkew(data, data); //错切
            /*------------------------------
            * 矩阵混合
            *  pre()前乘: 当前矩阵 X 该次使用的矩阵
            *  post()后乘: 该次使用的矩阵 X当前矩阵
            * ------------------------------*/
            matrix.preRotate(data); //会用 当前矩阵 X 该次的旋转矩阵
            matrix.postScale(data, data); // 本次缩放矩阵 X 当前矩阵
            /*------------------------------
            *  1.先旋转45度
            *  2.再平移(200, 200)
            * ------------------------------*/
            //后乘: 旋转后平移
            matrix.setRotate(45f);
            matrix.postTranslate(200, 200);
            //先乘: 平移前旋转
            matrix.setTranslate(200, 200);
            matrix.preRotate(45f);
            /*---------------------
            *         测试:
            * --------------------*/
            Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),
                    Bitmap.Config.ARGB_8888);        //创造bitmp的复制品bmp
            canvas = new Canvas(bmp);                //用bmp创造画布
            canvas.drawBitmap(bitmap, matrix, null); //根据bitmap以matrix变化后的图片, 在bmp上进行绘制
            imageView.setImageBitmap(bmp);
    }

    16、像素块处理

    1. 将图片分为像素块,改变像素块来处理图片。
    2. API:canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);,将第五个参数的坐标数组传入,bitmap会根据像素块数组,在WIDTH X HEIGHT网格中,每个焦点的坐标进行相应的修改。
    public class FlagImage extends View {
        Bitmap bitmap;
        //定义两个常量,这两个常量指定该图片横向20格,纵向上都被划分为10格
        private final int WIDTH = 30;
        private final int HEIGHT = 30;
        //记录该图像上包含的231个顶点
        private final int COUNT = (WIDTH +1) * (HEIGHT + 1);
        //定义一个数组,记录Bitmap上的21*11个点的坐标
        private  final  float[] verts = new float[COUNT * 2];
        //定义一个数组,记录Bitmap上的21*11个点经过扭曲后的坐标
        //对图片扭曲的关键就是修改该数组里元素的值
        private  final  float[] orig = new float[COUNT * 2];
    
        //振幅大小
        private final float A = 10;
        private float k = 0; //旗帜飞扬
    
        public FlagImage(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jide);
    
            float bitmapWidth = bitmap.getWidth();
            float bitmapHeight = bitmap.getHeight();
            int index = 0;
            for(int y = 0; y <= HEIGHT; y++){
                float fy = bitmapHeight * y / HEIGHT; //图像高度 乘以 y/总格数 可以获得 纵向y的坐标
                for(int x = 0;x<= WIDTH;x ++){
                    float fx = bitmapWidth * x/WIDTH; //x的坐标值
    
                    orig [index * 2 + 0] = verts [index * 2 + 0] = fx; //[(x1,y1), (x2,y2), (...)...]一维数组依次存储
                    orig [index * 2 + 1] = verts [index * 2 + 1] = fy+100; //这里人为将坐标+100是为了让图像下移,避免扭曲后被屏幕遮挡。
                    index += 1;
                }
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            flagWave();//旗帜飞扬
            k += 0.1F;
            //对bitmap按verts数组进行扭曲
            //从第一个点(由第5个参数0控制)开始扭曲
            canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);
            invalidate();
        }
    
        private void flagWave(){
            for(int j = 0; j <= HEIGHT; j++){
                for (int i = 0; i <= WIDTH; i++){
                    verts[(j * (WIDTH + 1) + i) * 2 + 0] += 0; //x值不变
                    float offsetY = (float)Math.sin((float)i/WIDTH*2*Math.PI + Math.PI * k);
                    verts[(j * (WIDTH + 1) + i) * 2 + 1] = orig[(j*WIDTH+i)*2+1]+offsetY*A;
                }
            }
        }
    
        private void flagWave(float cx, float cy){
            for(int i = 0; i < COUNT * 2; i += 2)
            {
                float dx = cx - orig[i + 0];
                float dy = cy - orig[i + 1];
                float dd = dx * dx + dy * dy;
                //计算每个坐标点与当前点(cx,cy)之间的距离
                float d = (float)Math.sqrt(dd);
                //计算扭曲度,距离当前点(cx,cy)越远,扭曲度越小
                float pull = 80000 / ((float)(dd * d));
                //对verts数组(保存bitmap 上21 * 21个点经过扭曲后的坐标)重新赋值
                if(pull >= 1)
                {
                    verts[i + 0] = cx;
                    verts[i + 1] = cy;
                }
                else
                {
                    //控制各顶点向触摸事件发生点偏移
                    verts[i + 0] = orig[i + 0] + dx * pull;
                    verts[i + 1] = orig[i + 1] + dx * pull;
                }
            }
            //通知View组件重绘
            invalidate();
        }
        public boolean onTouchEvent(MotionEvent event)
        {
    //        //调用warp方法根据触摸屏事件的坐标点来扭曲verts数组
    //        flagWave(event.getX() , event.getY());
              return true;
        }
    }

    17、PorterDuffXfermode的作用

    1. 用于设置两个图像交际区域的显示方式。
      2.

    18、PorterDuffXfermode绘制圆形图片

    1. 先将画布变成圆角矩形。再将图片绘制到画布上。
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.jide);
            Bitmap outBmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            /**======================================================
             * 用outbmp创建空白画布,并将outbmp的空白画布绘制成圆角长方形
             *====================================================*/
            Canvas canvas = new Canvas(outBmp); //用outbmp创建空白画布
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            canvas.drawRoundRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), 80, 80, paint);//先画出圆角长方形
            /**=========================================
            *    将bitmap绘制到圆角矩形的画布上(outBmp)
            *===========================================*/
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, 0, 0, paint);
            roundImageView.setImageBitmap(outBmp);

    19、PorterDuffXfermode绘制透明路径:刮刮卡效果

    1. 准备背景bitmap
    2. 准备灰色的bitmap
    3. 在外层灰色bitmap上用透明画笔绘制出路径(PorterDuffXfermode会将透明度与灰色bitmap融合,使得灰色bitmap在路径上变成透明)
    4. 在onDraw(Canvas canvas)整个View的canvas上先绘制背景bitmap,再绘制外层灰色bitmap
    public class CardImageView extends View {
        Bitmap mBgBitmap,mFgBitmap;
        Canvas mCanvas;
        Paint mPaint;
        Path mPath;
        public CardImageView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initCardImage();
        }
        private void initCardImage() {
            mPaint = new Paint();
            mPaint.setAlpha(0);  //将画笔的透明度设为0
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //目标的透明路径 覆盖在 外层图层之上, 让外层图层也透明
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND); //让画的线圆滑
            mPaint.setStrokeWidth(50);
            mPaint.setStrokeCap(Paint.Cap.ROUND); //圆滑
            mPath = new Path();
    
            mBgBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jide); //内层图层:图片
            mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(),mBgBitmap.getHeight(),Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mFgBitmap);
            mCanvas.drawColor(Color.GRAY); //外层图层为灰色
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    mPath.reset();
                    mPath.moveTo(event.getX(),event.getY());
                    break;
                case MotionEvent.ACTION_MOVE:
                    mPath.lineTo(event.getX(),event.getY());
                    break;
            }
            mCanvas.drawPath(mPath,mPaint); //给外层图层 画路径(路径画笔的透明色会让外层图层透明)
            invalidate();
            return  true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawBitmap(mBgBitmap,0,0,null); //1. 先绘制背景
            canvas.drawBitmap(mFgBitmap,0,0,null); //2. 再绘制外层有透明路径的Bitmap
        }
    }

    20、Shader是什么?

    1. 着色器、渐变器:用于渐变和渲染效果。
    2. 主要有BitmapShader(位图)、LinearGradient(线性)、RadialGradient(光束)、SweepGradient(梯度)、ComposeShader(混合)

    21、BitmapShader使用实例

    BitmapShader shader = new BitmapShader(bitmap, Shader.TitleMode.CLAMP, Shader.TitleMode.CLAMP); //1. 初始化
    Paint paint = new Paint();
    paint.setShader(shader); //2. 设置shader
    canvas.drawCircle(500, 250, 200, paint); //3. 绘制

    22、PathEffect

    1. 用想要的效果去绘制路径,比如让路径圆滑,出现噪点等:
    Path path = new Path(); //创造路径
    ...
    PathEffect pe = new ComposePathEffect(...);
    path.setPathEffect(pe); //设置路径
    canvas.drawPath(path, paint); //绘制路径

    参考资料

    1. CSDN layer详细讲解:http://blog.csdn.net/cquwentao/article/details/51423371
    2. Canvas类的最全面详解:https://www.jianshu.com/p/762b490403c3
    展开全文
  • 本文简要地介绍了如何将画法几何的某些方法应用于计算机绘图,主要叙述了两个方法一是根据建筑物、画面与视点的投影图推求三点透视变换矩阵的方法。另一是采用正投影法形成旋转曲面投影图的概念,定义了旋转曲面的自影...
  • 本文介绍Android的绘图机制,包括屏幕的尺寸信息,2D绘图中Canvas和paint的使用,XML绘图中bitmap\shape\selector\layer,如何用色彩矩阵处理图片的色彩(色调、饱和度、亮度),用变换矩阵进行图片处理以及画笔的特效...

    本文介绍Android的绘图机制,包括屏幕的尺寸信息,2D绘图中Canvas和paint的使用,XML绘图中bitmap\shape\selector\layer,如何用色彩矩阵处理图片的色彩(色调、饱和度、亮度),用变换矩阵进行图片处理以及画笔的特效处理

    问题汇总:

    带着问题学习、复习,效果更好,加油(ง •_•)ง!
    1. 4.7寸手机的4.7寸是什么?
    2. dp是什么?dp与px的区别。
    3. Canvas和Paint的作用。
    4. XML中Bitmap、shape、layer、selector作用
    5. shape有哪几种重要属性,各自的作用?
    6. Canvas的save()、restore()、tanslate()、rotate()的作用
    7. 位图Bitmap包含哪两部分,ARGB是什么?
    8. 色彩的三个要素和作用
    9. ColorMatrix的作用,用ColorMatrix的作用改变色彩三要素的思路
    10. 如何通过改变像素点的ARGB(以此来处理图片)
    11. 如何用图形变换矩阵Matrix处理图片
    12. 如何用像素块处理图片(drawBitmapMesh)
    13. PorterDuffXfermode作用和应用。
    14. shader作用和应用。
    15. PathEffect的作用和应用

    学习中看到有博客记录的很详细,有图:
    小仙女-android群英传之绘图机制和处理技巧

    1-屏幕尺寸信息

    1-屏幕参数

    1. 屏幕大小指的是屏幕对角线的长度,使用“寸”度量,4.7寸手机、5.5寸手机
    2. PPI:每英寸像素(Pixels Per Inch)又被称为DPI,对角线的像素点数除以屏幕的大小得到的。

    3-独立像素密度dp

    Android用mdpi即密度值为160的屏幕作为标准,在这个屏幕上1px = 1dp。例如100dp的长度,在mdpi中为100px,而在hdpi中为150px。

    因此dp用于屏幕适配最好。

    比例换算表 mdpi hdpi xhdpi xxhdpi
    dp 1 1 1 1
    px 1 1.5 2 3

    2-2D绘图基础

    系统提供Canvas提供绘图方法。还提供了各种绘制图像的API。如drawPoint点,drawLine线,矩形,多边形,弧,圆等。paint是重要的元素,能提供setAntiAlias()设置锯齿效果,setStyle()设置画笔的风格。通过画笔功能不同,组合各种API就能实现想要的效果。

    实例:简单测试Canvas

    public class TwoDActivity extends Activity {
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            /*将自定义控件设为ContentView-用于测试Canvas效果*/
            setContentView(new CustomeView(this));
        }
    
        /**-----------------------------------------
         *   自定义控件,重写draw方法,用于测试canvas
         * -----------------------------------------*/
        class CustomeView extends View{
            public CustomeView(Context context){
                super(context);
            }
    
            @Override
            public void draw(Canvas canvas) {
    
                /*---------------------------------
                *   绘制实心矩形
                * --------------------------------*/
                Paint paint = new Paint();
                paint.setStyle(Paint.Style.FILL); //画笔风格
                paint.setColor(Color.BLACK);      //画笔颜色
                canvas.drawRect(0, 0, 100, 100, paint);//绘制矩形
    
                /*---------------------------------
                *   绘制空心矩形
                * --------------------------------*/
                paint.setStyle(Paint.Style.STROKE); //画笔风格
                paint.setColor(Color.BLACK);        //画笔颜色
                canvas.drawRect(150, 0, 250, 100, paint);//绘制矩形
    
                /*-----------------------------------------------------------------
                *    在指定位置绘制文字-以(x,y)起点的水平直线为基准线,绘制直线Text
                * -----------------------------------------------------------------*/
                paint.setStyle(Paint.Style.FILL); //画笔风格
                paint.setTextSize(80);
                paint.setColor(Color.RED);        //画笔颜色
                canvas.drawText("Hello World!", 300, 100, paint);
                super.draw(canvas);
            }
        }
    }

    3-XML绘图基础

    XML不仅仅可以作为Java中的一个布局文件、配置列表,还可以绘制图画等内容。

    1-Bitmap

    可以将图片直接转为bitmap,用于程序中。

    <?xml version="1.0" encoding="utf-8"?>
    <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/blank"/>

    2-Shape

    XML绘图精华所在,无鸾是拟物化、扁平化还是渐变都可以。

    shape属性

    主要是6部分属性,省略部分具体细节,实际内容写写代码通过效果就可以掌握。(下列代码可以直接复制,可以看到效果)

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <!--shape可以为rectangle(默认),oval,line,ring-->
    
        <!--shape为rectangle使用, 默认为1dp-->
        <corners android:radius="5dp"/>
        <!--填充颜色-->
        <solid android:color="@color/colorAccent"/>
        <!--渐变色-->
        <gradient
            android:centerX="1"
            android:centerY="20"
            android:centerColor="@color/colorPrimary"
            android:endColor="@color/colorPrimaryDark"
            android:startColor="@color/colorAccent"
            android:type="linear"/>
        <padding />
        <!--制定边框, dashwidth虚线宽度,dashGap虚线间隔-->
        <stroke
            android:color="#334444"
            android:width="20dp"
            android:dashWidth="6dp"
            android:dashGap="2dp"/>
        <!--指定大小,一般在ImageView中配合scaleType属性使用-->
        <size />
    
    </shape>

    3-Layer

    类似于Photoshop图层,可以实现图层。

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:drawable="@color/colorAccent"/>
        <item
            android:drawable="@color/colorPrimary"
            android:left="50dp"
            android:top="50dp"
            android:right="50dp"
            android:bottom="50dp"/>
    </layer-list>

    4-Selector

    Selector用于帮助开发者实现静态绘图中的事件反馈,通过给不同事件设置图像,在获取相应输入后,返回相应结果。

    如同Button点击时候的效果,可以用selector自定义View的触摸反馈。

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true"
              android:drawable="@color/colorPrimaryDark">
            <shape />
        </item>
        <item android:state_pressed="false"
              android:drawable="@color/colorAccent">
            <shape />
        </item>
    </selector>

    这里就是点击和非点击时,显示相应图片,显示效果可以通过shape来实现。

    CSDN关于selector的博客:http://blog.csdn.net/pcaxb/article/details/47317251

    4-Android绘图技巧

    1-Canvas

    Canvas中有四个重要的方法:
    1. Canvas.save():将之前绘制内容都保存起来,接下来的绘制就好像在新的图层进行绘制一样。
    2. Canvas.restore():合并图层操作,将save之后的图像和save之前的图像合并起来。
    3. Canvas.tanslate():平移,将坐标系进行平移,绘制都以之后的坐标系为参照。
    4. Canvas.rotate():旋转,将坐标系进行旋转。避免了复杂运算,化繁为简。

    绘制时钟

    自定义时钟View

    private int mCenterX = 550; //自定义圆心X
        private int mCenterY = 800; //自定义圆心Y
        private int mRadius = 500; //圆的半径
    
        /**-----------------------------------------
         *           自定义钟表
         * -----------------------------------------*/
        class ClockView extends View{
            public ClockView(Context context){
                super(context);
            }
    
            @Override
            protected void onDraw(Canvas canvas) {
                //绘制圆形
                Paint paint = new Paint();
                paint.setAntiAlias(true);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(5);
                canvas.drawCircle(mCenterX, mCenterY, mRadius, paint);
    
                /*--------------------------------------------
                *  绘制刻度线: 1. 先在0点位置绘制竖线
                *             2. 将坐标系旋转30度
                *             3. 继续原样绘制竖线
                *             4. 循环绘制,最终绘制出所有刻度线
                * -------------------------------------------*/
                paint = new Paint();
                paint.setStrokeWidth(3);
                for(int i = 0; i < 12; i++){
                    //大刻度线
                    if(i == 0 || i == 3 || i == 6 || i == 9){
                        paint.setColor(Color.RED);
                        paint.setStrokeWidth(5);
                        canvas.drawLine(mCenterX, mCenterY-mRadius, mCenterX, mCenterY-mRadius+60, paint);
                        String strTime = i+"";
                        int textSize = 40;
                        paint.setTextSize(textSize);
                        canvas.drawText(strTime, mCenterX-textSize/3, mCenterY-mRadius+60+textSize, paint);
                    }else{
                        paint.setColor(Color.BLACK);
                        paint.setStrokeWidth(3);
                        canvas.drawLine(mCenterX, mCenterY-mRadius, mCenterX, mCenterY-mRadius+30, paint);
                        int textSize = 20;
                        String strTime = i+"";
                        paint.setTextSize(textSize);
                        canvas.drawText(strTime, mCenterX-textSize/3, mCenterY-mRadius+30+textSize, paint);
                    }
                    //旋转
                    canvas.rotate(30, mCenterX, mCenterY);
                }
                super.onDraw(canvas);
            }
        }

    2-Layer

    类似于Photoshop图层概念。Android使用saveLayer(),saveLayerAlpha()将一个图层入栈。restore(), restoreToCount()将一个图层出栈。入栈后,所有操作发生在该图层之上。出栈后,就会将图像绘制到上层Canvas上。

    CSDN layer详细讲解:http://blog.csdn.net/cquwentao/article/details/51423371

    5-图像处理:色彩特效处理

    Android中最常用的就是位图Bitmap,Bitmap包含了点阵和颜色值。点阵就是包含像素的矩阵。颜色值就是ARGB-对应透明度、红色、绿色、蓝色。

    这里只记录要点,详细内容请看原著或者网络博客。

    1-色彩矩阵分析

    图像描述的三个角度:
    1. 色调-物体显示的颜色
    2. 饱和度-颜色的纯度。0(灰度)到100%(饱和)来进行描述。
    3. 亮度-颜色相对的明暗程度。

    Android使用颜色矩阵ColorMatrix,4X5的矩阵。
    初始矩阵:不会对颜色产生任何变化

    - - - - - 偏移量
    决定R 1 0 0 0 0
    决定G 0 1 0 0 0
    决定B 0 0 1 0 0
    透明度 0 0 0 1 0

    改变颜色

    1-改变偏移量

    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1

    红色和绿色分量都增加100,红绿结合,导致颜色偏黄。

    2-改变颜色系数

    1 0 0 0
    0 2 0 0
    0 0 1 0
    0 0 0 1

    会导致

    3-改变色光属性

    色调、饱和度、亮度,Android都封装了一些API来快速调整这些参数,不用计算矩阵值。

    实例:通过seekbar选择设置图片的色调、饱和度和亮度。

    布局文件:包含各属性的seekbar
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.administrator.featherdemos.BitmapActivity"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="4" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="色调:"
                android:textColor="#000"
                android:textSize="23dp" />
    
            <SeekBar
                android:id="@+id/hue_seekbar"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="4" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="饱和度:"
                android:textColor="#000"
                android:textSize="23dp" />
    
            <SeekBar
                android:id="@+id/saturation_seekbar"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="4" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="亮度:"
                android:textColor="#000"
                android:textSize="23dp" />
    
            <SeekBar
                android:id="@+id/lum_seekbar"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="4" />
        </LinearLayout>
    
    </LinearLayout>
    Activity使用
    1. 初始化控件
    2. handleImageEffect:利用ColorMatrix设置色调、饱和度、亮度
    3. 给seekbar设置监听器—获取数值,并调用handleImageEffect处理图片,将最终结果设置到ImageView中显示。
    public class BitmapActivity extends Activity implements SeekBar.OnSeekBarChangeListener{
    
        ImageView imageView;
        SeekBar hueSeekBar;
        SeekBar saturationSeekBar;
        SeekBar lumSeekBar;
    
        Bitmap bitmap;
    
        float mHue = 0; //色调初始值为0, 原图色调
        float mSaturation = 1; //饱和度1,原图饱和度
        float mLum = 1; //亮度1,原图亮度
    
        //SeekBar的中间值
        int MID_VALUE = 127;
        //SeekBar的最大值
        int MAX_VALUE = 255;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_bitmap);
            imageView = (ImageView) findViewById(R.id.imageview);
            //从本地文件获取drawble
            Drawable drawable = ContextCompat.getDrawable(this, R.drawable.jide);
            bitmap = ((BitmapDrawable)drawable).getBitmap();
            imageView.setImageBitmap(bitmap);
    
            hueSeekBar = (SeekBar) findViewById(R.id.hue_seekbar);
            hueSeekBar.setMax(MAX_VALUE);
            hueSeekBar.setProgress(MID_VALUE);
    
            saturationSeekBar = (SeekBar) findViewById(R.id.saturation_seekbar);
            saturationSeekBar.setMax(MAX_VALUE);
            saturationSeekBar.setProgress(MID_VALUE);
    
            lumSeekBar = (SeekBar) findViewById(R.id.lum_seekbar);
            lumSeekBar.setMax(MAX_VALUE);
            lumSeekBar.setProgress(MID_VALUE);
    
            hueSeekBar.setOnSeekBarChangeListener(this);
            saturationSeekBar.setOnSeekBarChangeListener(this);
            lumSeekBar.setOnSeekBarChangeListener(this);
        }
    
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            switch(seekBar.getId()){
                case R.id.hue_seekbar:
                    mHue = (progress - MID_VALUE) * 1.0F / MID_VALUE * 180;
                    break;
                case R.id.saturation_seekbar:
                    mSaturation = progress * 1.0F  / MID_VALUE;
                    break;
                case R.id.lum_seekbar:
                    mLum =  progress * 1.0F  / MID_VALUE;
                    break;
                default:break;
            }
            imageView.setImageBitmap(handleImageEffect(mHue, mSaturation, mLum));
        }
    
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
    
        }
    
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
    
        }
    
        /**----------------------------------------------------
         * 处理图像的色调,饱和度,亮度。
         *   因为Android中不能处理原Bitmap,需要处理Bitmap的副本,
         *   因此使用原Bitmap创建副本,进行处理。
         * ---------------------------------------------------*/
        public Bitmap handleImageEffect(float hue, float saturation, float lum){
    
            //创建副本Bitmap
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.jide);
            Bitmap bitmap = bmp.copy(Bitmap.Config.ARGB_8888,true);
    
            //创建画板、画笔
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
    
            /*-----------------------------------
            * 处理色调: setRotate中0,1,2代表R,G,B
            * -----------------------------------*/
            ColorMatrix hueColorMatrix = new ColorMatrix();
            hueColorMatrix.setRotate(0, hue);
            hueColorMatrix.setRotate(1, hue);
            hueColorMatrix.setRotate(2, hue);
    
            /*-----------------------------------
            *  设置饱和度
            * -----------------------------------*/
            ColorMatrix saColorMatrix = new ColorMatrix();
            saColorMatrix.setSaturation(saturation);
    
            /*-------------------------------------------
            * 设置亮度:将三原色相同比例混合显示出白色,以此提高亮度
            * ------------------------------------------*/
            ColorMatrix lumColorMatrix = new ColorMatrix();
            lumColorMatrix.setScale(lum, lum, lum, 1);
    
            /*---------------------------------
            *  将矩阵作用效果混合, 叠加效果。
            * --------------------------------*/
            ColorMatrix colorMatrix = new ColorMatrix();
            colorMatrix.postConcat(hueColorMatrix);
            colorMatrix.postConcat(saColorMatrix);
            colorMatrix.postConcat(lumColorMatrix);
    
            /*-------------------------
            *  设置矩阵, 进行绘制
            * ------------------------*/
            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            canvas.drawBitmap(bitmap, 0, 0, paint);
            return bitmap;
        }
    }
    
    drawble图片

    我这里是ji.jpg,可以将该图片换为任何图片,切记图片不能太大,代码中没有进行OOM处理。

    2-Android颜色矩阵-ColorMatrix

    使用4X5颜色矩阵进行色彩处理。通过设置具体矩阵某元素来处理色彩。这里使用GridLayout动态创建4X5的EditText。

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3" />
    
        <GridLayout
            android:id="@+id/mGroup"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3"
            android:columnCount="5"
            android:rowCount="4">
    
        </GridLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.5"
            android:orientation="vertical">
    
            <Button
                android:id="@+id/btn_change"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:padding="10dp"
                android:text="Change"
                android:onClick="btnChange"
                android:textSize="20sp" />
    
            <Button
                android:id="@+id/btn_reset"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:padding="10dp"
                android:onClick="btnReset"
                android:text="Reset"
                android:textSize="20sp" />
        </LinearLayout>
    </LinearLayout>
    

    Activity

    获取矩阵中数据,并通过ColorMatrix作用到图像上。

    public class ColorMatrixActivity extends Activity {
    
        private Bitmap bitmap;
        private ImageView mImageView;
        private GridLayout mGroup;
        private EditText [] mEts = new EditText[20];
        private int mEtWidth,mEtHeight;
        private float[] mColorMatrix = new float[20];
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_color_matrix);
    
            bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jide);
    
            mImageView = (ImageView) findViewById(R.id.imageView);
            mGroup = (GridLayout) findViewById(R.id.mGroup);
            mImageView.setImageBitmap(bitmap);
            //无法在OnCreate中获取到View的宽高,通过post在视图创建后测量
            mGroup.post(new Runnable() {
                @Override
                public void run() {
                    //获取宽高信息
                    mEtWidth = mGroup.getWidth()/5;
                    mEtHeight = mGroup.getHeight()/4;
                    addEts();
                    initMatrix();
                }
            });
    
        }
    
        /*--------------------------------------
        *  将矩阵数组(一维)通过ColorMatrix作用到图像上
        *  以此对图片进行色彩处理
        * ------------------------------------*/
        private void setImageMatrix(){
            Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),
                    Bitmap.Config.ARGB_8888);
            ColorMatrix colorMatrix = new ColorMatrix();
            colorMatrix.set(mColorMatrix);
    
            Canvas canvas = new Canvas(bmp);
            Paint paint = new Paint();
            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            canvas.drawBitmap(bitmap,0, 0, paint);
            mImageView.setImageBitmap(bmp);
        }
    
    
        //添加EditText
        private void addEts(){
            for(int i = 0;i < 20;i++){
                EditText editText = new EditText(ColorMatrixActivity.this);
                mEts[i] = editText;
                mGroup.addView(editText,mEtWidth,mEtHeight);
            }
        }
    
        //初始化颜色矩阵为初始状态
        private void initMatrix(){
            for(int i= 0;i<20;i++){
                if(i % 6 ==0 ) {
                    mEts[i].setText(String.valueOf(1));
                }else{
                    mEts[i].setText(String.valueOf(0));
                }
            }
        }
    
        //获取矩阵值
        private void getMatrix(){
            for(int i = 0 ;i < 20;i++){
                mColorMatrix[i] = Float.valueOf(mEts[i].getText().toString());
            }
        }
    
        //作用点击事件
        public void btnChange(View view) {
            getMatrix();
            setImageMatrix();
        }
    
        //重置矩阵效果
        public void btnReset(View view) {
            initMatrix();
            getMatrix();
            setImageMatrix();
        }
    }

    3-常用色彩处理效果

    有灰度、反转、怀旧等。

    反转矩阵

    -1 0 0 1
    0 -1 0 1
    0 0 -1 1
    0 0 0 1

    其余不赘述,请查询资料。

    4-像素点处理

    可以通过改变每个像素点的ARGB值,进行色彩处理。Android提供Bitmap.getPixels(colorArray,省略...)来提取整个图片的像素点,并保存到数组中。

    r = Color.red(colorArray);
    g = Color.green(colorArray);
    b = Color.blue(colorArray);
    a = Color.alpha(colorArray);

    获取到原ARGB后,通过计算得到新的ARGB。
    r1 = i* r + j* g + k* b;

    newPix[i] = Color.argb(a, r1, g1, b1);
    bitmap.setPixels(newPix, ...);

    使用不同参数,就能达到老照片、浮雕等效果。

    6-图形特效处理

    图形变换类似于颜色变换。使用3X3变换矩阵进行变换。可以进行平移变换、缩放变换、旋转变换、错切变换。

    1-矩阵Matrix

    使用矩阵Matrix对图片进行平移、缩放、旋转、错切变换。

    public class PictureEditActivity extends Activity {
    
        ImageView imageView;
        static float data = 10f; //自定义的数据
        Bitmap bitmap;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_picture_edit);
    
            imageView = (ImageView) findViewById(R.id.pic_edit_imageview);
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.jide);
            //imageView.setImageBitmap(bitmap);
    
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    editPic();
                }
            }, 1000);
    
        }
    
        public void editPic(){
            Canvas canvas = new Canvas();
            /*------------------------------------
            * 使用矩阵处理图片
            * -----------------------------------*/
            float[] mImageMatrix = new float[9];
            Matrix matrix = new Matrix();
            matrix.setValues(mImageMatrix);//转为矩阵
            canvas.drawBitmap(bitmap, matrix, null);
    
            //set会覆盖整个矩阵
            matrix.setRotate(data); //旋转
            matrix.setTranslate(data, data);//平移
            matrix.setScale(data, data); // 缩放
            matrix.setSkew(data, data); //错切
            /*------------------------------
            * 矩阵混合
            *  pre()前乘: 当前矩阵 X 该次使用的矩阵
            *  post()后乘: 该次使用的矩阵 X当前矩阵
            * ------------------------------*/
            matrix.preRotate(data); //会用 当前矩阵 X 该次的旋转矩阵
            matrix.postScale(data, data); // 本次缩放矩阵 X 当前矩阵
            /*
            *  1.先旋转45度
            *  2.再平移(200, 200)
            * */
            //后乘: 旋转后平移
            matrix.setRotate(45f);
            matrix.postTranslate(200, 200);
            //先乘: 平移前旋转
            matrix.setTranslate(200, 200);
            matrix.preRotate(45f);
    
            /*---------------------
            *         测试:
            * --------------------*/
            Bitmap bmp = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),
                    Bitmap.Config.ARGB_8888);        //创造bitmp的复制品bmp
            canvas = new Canvas(bmp);                //用bmp创造画布
            canvas.drawBitmap(bitmap, matrix, null); //根据bitmap以matrix变化后的图片, 在bmp上进行绘制
            imageView.setImageBitmap(bmp);
        }
    }

    2-像素块

    例如色彩处理中像素点的处理,将图片分为像素块,改变像素块来处理图片。
    drawBitmapMesh()
    canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);,将第五个参数的坐标数组传入,bitmap会根据像素块数组,将WIDTH X HEIGHT网格中,每个焦点的坐标进行相应的修改。

    public class FlagImage extends View {
        Bitmap bitmap;
        //定义两个常量,这两个常量指定该图片横向20格,纵向上都被划分为10格
        private final int WIDTH = 30;
        private final int HEIGHT = 30;
        //记录该图像上包含的231个顶点
        private final int COUNT = (WIDTH +1) * (HEIGHT + 1);
        //定义一个数组,记录Bitmap上的21*11个点的坐标
        private  final  float[] verts = new float[COUNT * 2];
        //定义一个数组,记录Bitmap上的21*11个点经过扭曲后的坐标
        //对图片扭曲的关键就是修改该数组里元素的值
        private  final  float[] orig = new float[COUNT * 2];
    
        //振幅大小
        private final float A = 10;
        private float k = 0; //旗帜飞扬
    
        public FlagImage(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jide);
    
            float bitmapWidth = bitmap.getWidth();
            float bitmapHeight = bitmap.getHeight();
            int index = 0;
            for(int y = 0; y <= HEIGHT; y++){
                float fy = bitmapHeight * y / HEIGHT; //图像高度 乘以 y/总格数 可以获得 纵向y的坐标
                for(int x = 0;x<= WIDTH;x ++){
                    float fx = bitmapWidth * x/WIDTH; //x的坐标值
    
                    orig [index * 2 + 0] = verts [index * 2 + 0] = fx; //[(x1,y1), (x2,y2), (...)...]一维数组依次存储
                    orig [index * 2 + 1] = verts [index * 2 + 1] = fy+100; //这里人为将坐标+100是为了让图像下移,避免扭曲后被屏幕遮挡。
                    index += 1;
                }
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            flagWave();//旗帜飞扬
            k += 0.1F;
            //对bitmap按verts数组进行扭曲
            //从第一个点(由第5个参数0控制)开始扭曲
            canvas.drawBitmapMesh(bitmap,WIDTH,HEIGHT,verts,0,null,0,null);
            invalidate();
        }
    
        private void flagWave(){
            for(int j = 0; j <= HEIGHT; j++){
                for (int i = 0; i <= WIDTH; i++){
                    verts[(j * (WIDTH + 1) + i) * 2 + 0] += 0; //x值不变
                    float offsetY = (float)Math.sin((float)i/WIDTH*2*Math.PI + Math.PI * k);
                    verts[(j * (WIDTH + 1) + i) * 2 + 1] = orig[(j*WIDTH+i)*2+1]+offsetY*A;
                }
            }
        }
    
        private void flagWave(float cx, float cy){
            for(int i = 0; i < COUNT * 2; i += 2)
            {
                float dx = cx - orig[i + 0];
                float dy = cy - orig[i + 1];
                float dd = dx * dx + dy * dy;
                //计算每个坐标点与当前点(cx,cy)之间的距离
                float d = (float)Math.sqrt(dd);
                //计算扭曲度,距离当前点(cx,cy)越远,扭曲度越小
                float pull = 80000 / ((float)(dd * d));
                //对verts数组(保存bitmap 上21 * 21个点经过扭曲后的坐标)重新赋值
                if(pull >= 1)
                {
                    verts[i + 0] = cx;
                    verts[i + 1] = cy;
                }
                else
                {
                    //控制各顶点向触摸事件发生点偏移
                    verts[i + 0] = orig[i + 0] + dx * pull;
                    verts[i + 1] = orig[i + 1] + dx * pull;
                }
            }
            //通知View组件重绘
            invalidate();
        }
        public boolean onTouchEvent(MotionEvent event)
        {
    //        //调用warp方法根据触摸屏事件的坐标点来扭曲verts数组
    //        flagWave(event.getX() , event.getY());
              return true;
        }
    }

    7-画笔特效处理

    1-PorterDuffXfermode

    用于设置两个图像交际区域的显示方式。以此可以制作圆形图片等效果。

    圆形图片

    先将画布变成圆角矩形。再将图片绘制到画布上。

            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.jide);
            Bitmap outBmp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(outBmp); //用outbmp创建空白画布
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            canvas.drawRoundRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), 80, 80, paint);//先画出圆角长方形
    
            /*
            * 将bitmap绘制到圆角矩形的画布上(outBmp)
            * */
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(bitmap, 0, 0, paint);
            roundImageView.setImageBitmap(outBmp);

    刮刮卡效果

    1. 准备背景bitmap
    2. 准备灰色的bitmap
    3. 在外层灰色bitmap上用透明画笔绘制出路径(PorterDuffXfermode会将透明度与灰色bitmap融合,使得灰色bitmap在路径上变成透明)
    4. 在onDraw(Canvas canvas)整个View的canvas上先绘制背景bitmap,再绘制外层灰色bitmap
    public class CardImageView extends View {
        Bitmap mBgBitmap,mFgBitmap;
        Canvas mCanvas;
        Paint mPaint;
        Path mPath;
    
        public CardImageView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initCardImage();
        }
    
        private void initCardImage() {
            mPaint = new Paint();
            mPaint.setAlpha(0);  //将画笔的透明度设为0
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //目标的透明路径 覆盖在 外层图层之上, 让外层图层也透明
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND); //让画的线圆滑
            mPaint.setStrokeWidth(50);
            mPaint.setStrokeCap(Paint.Cap.ROUND); //圆滑
            mPath = new Path();
    
            mBgBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jide); //内层图层:图片
            mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(),mBgBitmap.getHeight(),Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mFgBitmap);
            mCanvas.drawColor(Color.GRAY); //外层图层为灰色
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    mPath.reset();
                    mPath.moveTo(event.getX(),event.getY());
                    break;
                case MotionEvent.ACTION_MOVE:
                    mPath.lineTo(event.getX(),event.getY());
                    break;
            }
            mCanvas.drawPath(mPath,mPaint); //给外层图层 画路径(路径画笔的透明色会让外层图层透明)
            invalidate();
            return  true;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawBitmap(mBgBitmap,0,0,null);
            canvas.drawBitmap(mFgBitmap,0,0,null);
        }
    }

    2-Shader

    着色器、渐变器:用于渐变和渲染效果。主要有BitmapShader(位图)、LinearGradient(线性)、RadialGradient(光束)、SweepGradient(梯度)、ComposeShader(混合)

    BitmapShader shader = new BitmapShader(bitmap, Shader.TitleMode.CLAMP, Shader.TitleMode.CLAMP); //初始化
    Paint paint = new Paint();
    paint.setShader(shader); //设置shader
    canvas.drawCircle(500, 250, 200, paint); //绘制

    其余的使用和例程就省略了,有兴趣的参考开头的博客或者原著。
    主要就是选择需要的Shader,并且在Paint里面setShader,就可以去绘制了。

    3-PathEffect

    用想要的效果去绘制路径,比如让路径圆滑,出现噪点等。主要使用方法如下:

    Path path = new Path(); //创造路径
    ...
    PathEffect pe = new ComposePathEffect(...);
    path.setPathEffect(pe); //设置路径
    canvas.drawPath(path, paint); //绘制路径
    展开全文
  • MATLAB拟合出的代码绘图睡眠时分析大脑的连通性 梅兰妮·伯恩哈特(MélanieBernhardt) 学期项目-数据科学课程研究 主管:J. Buhmann,顾问:D. Miladinovic 苏黎世联邦理工学院-机器学习学院 在这个学期的项目中...
  • MATLAB拟合出的代码绘图 Hartoyo等人采用的方法和数据集的实现。 (2019) 为了检查神经人口模型的可识别性和草率,我们将其拟合到一个脑电图谱,并估计了22个未知参数的后验分布。 然后,我们表征此分布的属性,...
  • 1.问题描述  在使用matlab编程时,有时需要像C语言中数组一类的数据类型来存储数据。就一维数组而言,它相当于矩阵的一行或者...而我们一般都是采用矩阵计算系统输出与输入的关系,若要简单绘图命令plot来绘制此三
  • Matlab scatter 如何显示不同颜色点状

    千次阅读 2017-05-27 08:44:00
    有时候需要在matlab scatter绘图中显示不同颜色... matlab 如何实现呢? 1.创建一维矩阵x,y1,y2 分别表示年龄、高压和低压 x=[75;78;51;82;77;88;41;78;78;61;71;74;62;81;75;64;80;72;51;80;56;73] y1=[208;146...
  • 在使用Python绘制图表前,我们需要先安装两个库文件numpy和matplotlib。Numpy是Python开源的数值计算扩展,可用来存储和处理...下面我通过一些简单的代码介绍如何使用 Python绘图。一、图形绘制直方图importmatplotl...
  • 【导读】专知成员Hui上一次为大家介绍Matplotlib的使用,包括绘图,绘制点和线,以及图像的轮廓和直方图,这一次为大家详细讲解Numpy工具包中的各种工具,并且会举实例说明如何应用。Numpy是非常有名的python科学...
  • 数据可视化理论学习

    2021-02-12 16:22:16
    如果我们手中 只有解决具体问题的工具,...如何用向量来描述点和线段? 一个向量包含有长度和方向信息 在可视化的许多应用场景中,我们都 要处理成百上千的图形。如果这个时候,我们在原始坐标下通过计算顶点来绘制图
  • 2.2.4 实际中如何用哈尔或沃尔什函数构建图像变换矩阵? 58 2.2.5 哈尔变换的基元图像看起来是什么样的? 61 2.2.6 可以定义元素仅为+1 或.1 的正交矩阵吗? 65 B2.5 对沃尔什函数的排列方式 65 2.2.7 哈达玛/...
  • 在计算机图像学中,通过增加一个比例因子,很以对图像进行比例变换操作,由于该比例因子可以增加或减少所有向量的长短,这样就可以无须重新绘图而很以地改变向量的尺寸。 结尾点题 刚体在三维空间中通过位置与...
  • 02 | 指令式绘图系统:如何用Canvas绘制层次关系图? 01 | 浏览器中实现可视化的四种方式 路线 要点 图形基础:带你熟悉HTML/CSS、SVG、Canvas2D和WebGL这四种图形系统,学会它们的基本用法、优点和局限性,从而能在...
  • WebGL编程指南

    2018-11-26 18:04:36
    247 示例程序(perspectiveview.js) 249 投影矩阵的作用 251 共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除...
  • 共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • WebGL编程指南.rar

    热门讨论 2015-04-09 12:16:56
    共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • WEBGL编程指南pdf

    热门讨论 2015-09-17 14:34:13
    共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • WebGL编程指南压缩包

    2015-05-15 11:44:05
    共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • 共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • 共冶一炉(模型矩阵、视图矩阵和投影矩阵) 252 示例程序(PerspectiveView_mvp.js) 254 示例程序做实验 257 正确处理对象的前后关系 258 隐藏面消除 260 示例程序(DepthBuffer.js) 262 深度冲突 263 ...
  • 该软件是 Python 编写的,这是一种高级跨平台编程语言,GUI 是 wxPython 设计的,无论操作系统如何,它都能提供一致的外观。 数字运算(如矩阵和线性代数)由 Numpy 模块执行,所有图形功能均由 Matplolib 库...

空空如也

空空如也

1 2 3 4 5
收藏数 92
精华内容 36
关键字:

如何用矩阵绘图