Android图形处理-百变Paint

   <h2><strong>Android图形处理-百变Paint</strong></h2>    <h2><strong>Paint的基本属性</strong></h2>    <p>在 Android图形处理-Canvas 已经有了基本的使用,但是这节介绍几个好玩的属性</p>    <h3><strong>设置阴影和渐变</strong></h3>    <p>设置渐变</p>    <p>主要是给画笔(Paint)设置一个Shader</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ebed88d4ebe13639f1d5a481628cf8bf.png"></p>    <p style="text-align:center">sp161108_143636</p>    <pre>  <code class="language-java">Paint paint = new Paint();          LinearGradient linearShader = new LinearGradient(0, 0, 100, 100,                  new int[]{Color.RED, Color.BLACK, Color.BLUE, Color.DKGRAY},                  null, Shader.TileMode.CLAMP);          paint.setShader(linearShader);          canvas.drawCircle(100,100,100,paint);</code></pre>    <p>LinearGradient是Shader的子类。其他子类:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/11608f13adb33856a9f94359622ea0bc.png"></p>    <p style="text-align:center">sp161108_142705</p>    <p>LinearGradient构造方法的含义:</p>    <pre>  <code class="language-java">/** Create a shader that draws a linear gradient along a line.          @param x0           The x-coordinate for the start of the gradient line          @param y0           The y-coordinate for the start of the gradient line          @param x1           The x-coordinate for the end of the gradient line          @param y1           The y-coordinate for the end of the gradient line          @param  colors      The colors to be distributed along the gradient line          @param  positions   May be null. The relative positions [0..1] of                              each corresponding color in the colors array. If this is null,                              the the colors are distributed evenly along the gradient line.          @param  tile        The Shader tiling mode      */</code></pre>    <p>前两个参数是开始点,接下来是结束点,colors是颜色的数组,positions是分布的模式,tile是渐变的模式比如可重复等</p>    <p>设置阴影</p>    <pre>  <code class="language-java">paint.setShadowLayer(100,20,20,Color.RED);          paint.setColor(getResources().getColor(R.color.colorAccent));          canvas.drawCircle(100,100,50,paint);</code></pre>    <p>核心是setShadowLayer</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d8c97460a11605cf5387819d7214b95a.png"></p>    <p style="text-align:center">sp161108_144655</p>    <h3><strong>画笔效果</strong></h3>    <p><strong>PathEffect</strong></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6d95f2229d30763014a0f89a40f3d9a9.png"></p>    <p style="text-align:center">sp161108_145217</p>    <p>这个表示画笔的样式的基类</p>    <ul>     <li> <p>CornerPathEffect</p> </li>    </ul>    <pre>  <code class="language-java">CornerPathEffect cornerPathEffect = new CornerPathEffect(40);          paint.setPathEffect(cornerPathEffect);</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c4f4597e35bca2434fb8de5434ab5d25.png"></p>    <p style="text-align:center">sp161108_145557</p>    <p>构造参数表示拐角的半径</p>    <ul>     <li> <p>DiscretePathEffect</p> </li>    </ul>    <pre>  <code class="language-java">DiscretePathEffect discretePathEffect = new DiscretePathEffect(5.0f, 5.0f);          paint.setPathEffect(discretePathEffect);</code></pre>    <p>第一个参数控制震动的频率,第二个参数控制震动的幅度</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a8863189c498614459ffec99edbfccdc.png"></p>    <p style="text-align:center">sp161108_145913</p>    <ul>     <li> <p>DashPathEffect</p> </li>    </ul>    <pre>  <code class="language-java">DashPathEffect dashPathEffect = new DashPathEffect(new float[]{8.0f, 6.0f, 7.0f, 4.0f}, 0);          paint.setPathEffect(dashPathEffect);</code></pre>    <p>第一个参数是每个破折线(dash)的随机长度</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4b141aabb3c5b20a2fd279839e3edffa.png"></p>    <p style="text-align:center">sp161108_150434</p>    <ul>     <li> <p>PathDashPathEffect</p> </li>    </ul>    <pre>  <code class="language-java">Path path1 = new Path();          path1.addCircle(0,0,4, Path.Direction.CCW);            PathDashPathEffect pathDashPathEffect = new PathDashPathEffect(path1, 30, 0, PathDashPathEffect.Style.ROTATE);          paint.setPathEffect(pathDashPathEffect);</code></pre>    <p>这也是虚线但是这个虚线段是可以自己设置形状的</p>    <p>第一个参数是一个路径,但是这个路径要画出一个形状,第二个参数是两个虚线之间的距离</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/690556cd1e32a0e6431a096166cc5e6d.png"></p>    <p style="text-align:center">sp161108_150946</p>    <p>画出一个五角星,注意角度是18和36度:</p>    <pre>  <code class="language-java">Path path1 = new Path();          path1.moveTo(0, 100-(float) Math.sin(Math.PI * 18 / 180) * 100);          path1.lineTo((float) (Math.cos(Math.PI * 18 / 180) * 200), 100-(float) Math.sin(Math.PI * 18 / 180) * 100);          path1.lineTo((float) (Math.cos(Math.PI * 18 / 180) * 100)-(float) Math.sin(Math.PI * 36 / 180) * 100,                  100+(float) (Math.cos(Math.PI * 18 / 180) * 100));          path1.lineTo((float) (Math.cos(Math.PI * 18 / 180) * 100),0);          path1.lineTo((float) (Math.cos(Math.PI * 18 / 180) * 100)+(float) Math.sin(Math.PI * 36/ 180) * 100,                  100+(float) (Math.cos(Math.PI * 18 / 180) * 100));          path1.lineTo(0, 100-(float) Math.sin(Math.PI * 18 / 180) * 100);</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/75fbcb2603bce1c6a285e4815679b46d.png"></p>    <p style="text-align:center">sp161108_155132</p>    <p>在缩小之后把五角星应用到虚线中:</p>    <p>但是在等比例缩小10倍之后五角星没有正确绘制,发生变形了:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/da7efec6c109b424fa0b70dc8542beeb.png"></p>    <p style="text-align:center">sp161108_155337</p>    <ul>     <li> <p>ComposePathEffect</p> </li>    </ul>    <pre>  <code class="language-java">DiscretePathEffect discretePathEffect = new DiscretePathEffect(5.0f, 5.0f);    PathDashPathEffect pathDashPathEffect = new PathDashPathEffect(path1, 30, 0, PathDashPathEffect.Style.ROTATE);            ComposePathEffect composePathEffect = new ComposePathEffect(discretePathEffect, pathDashPathEffect);          paint.setPathEffect(composePathEffect);</code></pre>    <p>创建一个组合的效果,是一个在外面一个在内侧</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ea6083f713ba78eb142418d1b605d241.png"></p>    <p style="text-align:center">sp161108_155657</p>    <ul>     <li> <p>SumPathEffect</p> </li>    </ul>    <pre>  <code class="language-java">SumPathEffect sumPathEffect = new SumPathEffect(discretePathEffect, pathDashPathEffect);</code></pre>    <p>和上面的不同这是一个复合效果</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8f07cd04ef3cfaed4e65888068d59190.png"></p>    <p style="text-align:center">sp161108_155941</p>    <p>区别很明显,因为两个都是相同的效果“叠加”得到的</p>    <p>光棍节快到了</p>    <p>参考 android制作闪动的红心</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5754462df8904447704c5af78b586d41.png"></p>    <p style="text-align:center">sp161108_162225</p>    <pre>  <code class="language-java">int px = getMeasuredWidth() / 2;          int py = getMeasuredHeight() / 2;          // 路径的起始点          path.moveTo(px, py - 5*5 );          // 根据心形函数画图          for (double i = 0; i <= 2 * Math.PI; i += 0.001) {  //          注意这里得到的xy不是真实的坐标要在进行减法              float x = (float) (16 * Math.sin(i) * Math.sin(i) * Math.sin(i));              float y = (float) (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i));              x *= 5;              y *= 5;              x = px - x;              y = py - y;              path.lineTo(x, y);          }          canvas.drawPath(path, paint);</code></pre>    <p><strong>DrawTextOnPath</strong></p>    <p>注意在paint写文字的时候setStyle方法依旧有效,设置 paint.setStyle(Paint.Style.STROKE) 就会产生空心字体的效果</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/7fdf18ed4e76b70c2a2188f31059a7e7.png"></p>    <p style="text-align:center">sp161108_163150</p>    <p>注意在写字之前一定先要移动面板然后在写</p>    <pre>  <code class="language-java">Path path = new Path();          path.moveTo(0, 0);          path.lineTo(100, 100);          path.lineTo(150, 190);          path.lineTo(400, 240);          canvas.drawPath(path,paint);          canvas.save();          canvas.translate(0, 50);          canvas.drawTextOnPath("你好",path, 10, 10, paint);          canvas.restore();</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d43ad5513a886ddc0cc45e8c0157df0d.png"></p>    <p style="text-align:center">sp161108_163647</p>    <p>drawTextOnPath中两个float参数负责调整字体和path的偏移量</p>    <h3>设置Mask效果</h3>    <p>面具效果的根类是MaskFilter,它两个子类,也就是有两个效果,一个是模糊一个是“突出化”</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/820149226bc92f87cb29d036f9514cfa.png"></p>    <p style="text-align:center">sp161108_163858</p>    <p><strong>设置模糊效果</strong></p>    <p>在上面的代码中更改:</p>    <pre>  <code class="language-java">BlurMaskFilter blurMaskFilter = new BlurMaskFilter(5, BlurMaskFilter.Blur.NORMAL);          paint.setMaskFilter(blurMaskFilter);</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e4d4b7616fca8ccee9888a3c05ef1609.png"></p>    <p style="text-align:center">sp161109_092018</p>    <p>第一个参数是模糊半径第二个参数是模糊的样式</p>    <p>设置突出化的效果</p>    <p>设置突出化就是可以在一个3D的场景中设置光源、光源的距离等从而造成效果:</p>    <pre>  <code class="language-java">EmbossMaskFilter embossMaskFilter = new EmbossMaskFilter(new float[]{1.5f, 1.5f, 1.5f}, 1f, 10, 6.2f);</code></pre>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/be58a2f5687c</p>    <p> </p>