| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
windows7
8年前发布

Android 画笔Paint

   <p>了解Android Paint,一篇就够。引用Aige《 自定义控件其实很简单 》系列博客的话“很多时候你压根不需要了解太多原理,只需站在巨人的丁丁上即可”,所谓前人种树后人好乘凉,这里记录下我的实践结果。</p>    <p>我们可以通过Paint中setter方法来为画笔设置属性:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/26463eb336c38696a0c93ed48551b5cb.jpg"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/949c3afeebf1cb0a0fa7e3c1bc75ca82.jpg"> <img src="https://simg.open-open.com/show/47318437494d500ba04812ca55583ab0.jpg"></p>    <p>浩浩荡荡来将这些方法一一过一遍:</p>    <h2><strong>set</strong></h2>    <pre>  <code class="language-java">void set(Paint src)</code></pre>    <p>为当前画笔copy一个画笔</p>    <h2><strong>setARGB</strong></h2>    <pre>  <code class="language-java">void  setARGB(int a, int r, int g, int b)</code></pre>    <p>设置Paint对象颜色,a代表透明度,r,g,b代表颜色值</p>    <p>插播:RGB与十六进制区别</p>    <p>一般在xml里定义颜色可以直接写:</p>    <pre>  <code class="language-java">android:textColor="#FF6281"</code></pre>    <p>但是在code代码中就必须写成这样:</p>    <pre>  <code class="language-java">text.setTextColor(0xffff6281);</code></pre>    <p>xml中透明度写不写无所谓,默认是ff不透明,但是代码中用十六进制0x来表示,就必须跟上ff透明度,不然会默认00全透明。</p>    <h2><strong>setAlpha</strong></h2>    <pre>  <code class="language-java">void  setAlpha(int a)</code></pre>    <p>设置alpha透明度,范围为0~255</p>    <h2><strong>setAntiAlias</strong></h2>    <pre>  <code class="language-java">void  setAntiAlias(boolean aa)</code></pre>    <p>是否抗锯齿</p>    <h2><strong>setColor</strong></h2>    <pre>  <code class="language-java">void  setColor(int color)</code></pre>    <p>设置paint颜色</p>    <h2><strong>setColorFilter</strong></h2>    <pre>  <code class="language-java">ColorFilter setColorFilter (ColorFilter filter)</code></pre>    <p>设置颜色过滤, ColorFilter 有三个子类去实现ColorMatrixColorFilter、LightingColorFilter和PorterDuffColorFilter</p>    <h2><strong>ColorMatrixColorFilter</strong></h2>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       //省略构造方法       private void init() {           mPaint = new Paint();           mPaint.setAntiAlias(true);           // 生成色彩矩阵           ColorMatrix colorMatrix = new ColorMatrix(new float[]{                0.5F, 0, 0, 0, 0,                0, 0.5F, 0, 0, 0,                0, 0, 0.5F, 0, 0,                0, 0, 0, 1, 0,           });           mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));       }         @Override       protected void onDraw(Canvas canvas) {            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.logo);            canvas.drawBitmap(bitmap, 0, 0, mPaint);       }    }</code></pre>    <p>第一行表示的R(红色)的向量,第二行表示的G(绿色)的向量,第三行表示的B(蓝色)的向量,最后一行表示A(透明度)的向量,这一顺序必须要正确不能混淆!这个矩阵不同的位置表示的RGBA值,其范围在0.0F至2.0F之间,1为保持原图的RGB值。每一行的第五列数字表示偏移值。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8ffb6a665da38ef20c987144bd2481f8.jpg"></p>    <p>这是原图效果,增加ColorMatrix,效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/93dc6f5e3949226d1dd36896a31fe73a.jpg"></p>    <h2><strong>LightingColorFilter</strong></h2>    <p>只有一个构造方法, LightingColorFilter (int mul, int add) ,参数1:mul全称是colorMultiply意为色彩倍增;参数2:add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB。</p>    <pre>  <code class="language-java">// 设置颜色过滤,去掉绿色  mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000));</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3fcaa2f6cce211915a9e74ac662f1b82.jpg"></p>    <h2><strong>PorterDuffColorFilter</strong></h2>    <p>也只有一个构造方法, PorterDuffColorFilter (int color, PorterDuff.Mode mode) ,参数1:16进制表示的颜色值;参数2:PorterDuff内部类Mode中的一个常量值,这个值表示混合模式。</p>    <pre>  <code class="language-java">// 设置颜色过滤,Color的值设为红色,模式PorterDuff.Mode.DARKEN变暗  mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN));</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/19766c03d0e38df30d931cfbe9f7a57c.jpg"></p>    <p>混合模式还有很多,不仅是应用于图像色彩混合,还应用于图形混合。</p>    <h2><strong>setDither</strong></h2>    <pre>  <code class="language-java">void setDither(boolean dither)</code></pre>    <p>设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰</p>    <h2><strong>setFakeBoldText</strong></h2>    <pre>  <code class="language-java">void setFakeBoldText(boolean fakeBoldText)</code></pre>    <p>设置伪粗体文本</p>    <h2><strong>setFilterBitmap</strong></h2>    <pre>  <code class="language-java">void setFilterBitmap(boolean filter)</code></pre>    <p>设置位图进行滤波处理</p>    <h2><strong>setHinting</strong></h2>    <pre>  <code class="language-java">void setHinting (int mode)</code></pre>    <p>Added in API level 14,设置暗示模式,HINTING_OFF 或 HINTING_ON</p>    <h2><strong>setLetterSpacing</strong></h2>    <pre>  <code class="language-java">void setLetterSpacing (float letterSpacing)</code></pre>    <p>Added in API level 21,设置文本字母间距,默认0,负值收紧文本</p>    <h2><strong>setLinearText</strong></h2>    <pre>  <code class="language-java">void setLinearText(boolean linearText)</code></pre>    <p>设置线性文本</p>    <h2><strong>setMaskFilter</strong></h2>    <pre>  <code class="language-java">MaskFilter setMaskFilter (MaskFilter maskfilter)</code></pre>    <p>设置滤镜的效果, <a href="/misc/goto?guid=4959722862673959030" rel="nofollow,noindex">MaskFilter</a> 有两个子类实现BlurMaskFilter, EmbossMaskFilter</p>    <h2><strong>BlurMaskFilter</strong></h2>    <p>设置画笔模糊阴影效果</p>    <pre>  <code class="language-java">mPaint.setMaskFilter(new BlurMaskFilter(20f, BlurMaskFilter.Blur.SOLID));</code></pre>    <p>参数1:模糊延伸半径,必须>0;</p>    <p>参数2:有四种枚举</p>    <p>NORMAL,同时绘制图形本身内容+内阴影+外阴影,正常阴影效果</p>    <p>INNER,绘制图形内容本身+内阴影,不绘制外阴影</p>    <p>OUTER,不绘制图形内容以及内阴影,只绘制外阴影</p>    <p>SOLID,只绘制外阴影和图形内容本身,不绘制内阴影</p>    <p>BlurMaskFilter绘制的Bitmap基本完全不受影响</p>    <p>四种枚举效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/dccb0959895cfda8852bb25d998667d5.jpg"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/15905ac3530af06d49b612bf14979aee.jpg"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ec48b2b3300abfe45354b5ac8678b510.jpg"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d72ec5fdbb8be1ddb057151369c4dc0a.jpg"></p>    <h2><strong>EmbossMaskFilter</strong></h2>    <pre>  <code class="language-java">//Paint的setMaskFilter不被GPU支持,为了确保画笔的setMaskFilter能供起效,我们需要禁用掉GPU硬件加速或AndroidManifest.xml文件中设置android:hardwareAccelerated为false  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {       //View从API Level 11才加入setLayerType方法       //设置软件渲染模式绘图       this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);  }  //设置浮雕滤镜效果,参数1:光源指定方向;参数2:环境光亮度,取值0-1,值越小越暗;参数3:镜面高光反射系数,值越小反射越强;参数4:模糊延伸半径  mPaint.setMaskFilter(new EmbossMaskFilter(new float[]{1, 1, 1}, 0.4f, 8f, 3f));</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5c1053c02497867652039215efd558ef.jpg"></p>    <h2><strong>setPathEffect</strong></h2>    <pre>  <code class="language-java">PathEffect  setPathEffect(PathEffect effect)</code></pre>    <p>设置路径效果, PathEffect 有6个子类实现ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect</p>    <p>具体代码:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {   private Paint mPaint;   // 路径对象   private Path mPath;   private PathEffect[] pathEffects = new PathEffect[7];   private float mPhase=5;    //省略构造方法    private void init() {       mPaint = new Paint();       mPaint.setStyle(Paint.Style.STROKE);       mPaint.setStrokeWidth(5);       mPaint.setAntiAlias(true);       initPath();    }    private void initPath() {       // 实例化路径       mPath = new Path();       // 定义路径的起点       mPath.moveTo(10, 50);         // 定义路径的各个点       for (int i = 0; i <= 30; i++) {            mPath.lineTo(i * 35, (float) (Math.random() * 100));       }       //什么都不处理       pathEffects[0] = null;       //参数1:线段之间的圆滑程度       pathEffects[1] = new CornerPathEffect(10);       //参数1:间隔线条长度(length>=2),如float[] {20, 10}的偶数参数20定义了我们第一条实线的长度,       //而奇数参数10则表示第一条虚线的长度,后面不再有数据则重复第一个数以此往复循环;参数2:虚实线间距       pathEffects[2] = new DashPathEffect(new float[]{20, 10}, mPhase);       //参数1:值越小杂点越密集;参数2:杂点突出的大小,值越大突出的距离越大       pathEffects[3] = new DiscretePathEffect(5.0f, 10.0f);       Path path = new Path();       path.addRect(0, 0, 8, 8, Path.Direction.CCW);       //定义路径虚线的样式,参数1:path;参数2:实线的长度;参数3:虚实线间距       pathEffects[4] = new PathDashPathEffect(path, 20, mPhase, PathDashPathEffect.Style.ROTATE);       pathEffects[5] = new ComposePathEffect(pathEffects[2], pathEffects[4]);       //ComposePathEffect和SumPathEffect都可以用来组合两种路径效果,具体区别(不知道如何描述)小伙伴们自己试试       pathEffects[6] = new SumPathEffect(pathEffects[4], pathEffects[3]);   }    @Override  protected void onDraw(Canvas canvas) {       /*        * 绘制路径        */       for (int i = 0; i < pathEffects.length; i++) {            mPaint.setPathEffect(pathEffects[i]);            canvas.drawPath(mPath, mPaint);            // 每绘制一条将画布向下平移250个像素            canvas.translate(0, 250);       }  }    }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/9fcd97f17c368cde19c2761a0227db9c.png"></p>    <h2><strong>setRasterizer</strong></h2>    <p>Rasterizer setRasterizer(Rasterizer rasterizer)</p>    <p>设置光栅化,API21已过时</p>    <h2><strong>setShader</strong></h2>    <pre>  <code class="language-java">Shader  setShader(Shader shader)</code></pre>    <p>设置着色器, <a href="/misc/goto?guid=4959722862768017348" rel="nofollow,noindex">Shader</a> 子类实现有BitmapShader, ComposeShader, LinearGradient, RadialGradient, SweepGradient</p>    <h2><strong>BitmapShader</strong></h2>    <p>对图形进行渲染,构造方法:</p>    <pre>  <code class="language-java">BitmapShader (Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)</code></pre>    <p>tileX、tileY参数Shader.TileMode有三个:</p>    <p>CLAMP 重复最后一个颜色至最后</p>    <p>MIRROR 重复着色的图像水平或垂直方向已镜像方式填充会有翻转效果</p>    <p>REPEAT 重复着色的图像水平或垂直方向</p>    <p>设置tileX、tileY为Shader.TileMode.CLAMP</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private Context mContext;       private Bitmap mBitmap;       private BitmapShader mShader;         // 省略构造方法         private void init() {            mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.logo);            mShader= new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            mPaint = new Paint();            mPaint.setAntiAlias(true);       }         @Override       protected void onDraw(Canvas canvas) {            mPaint.setShader(mBitmapShader);            canvas.drawCircle(500, 550, 500, mPaint);       }    }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/35cbdd522a256ba4ef3501d655a29046.jpg"></p>    <p>设置tileX、tileY为Shader.TileMode.MIRROR</p>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/25590da3b6d1bcf5a547554013d8c649.jpg"></p>    <p>设置tileX、tileY为Shader.TileMode.REPEAT</p>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3a498524e379523479c2ddadb1fbd2c0.jpg"></p>    <h2><strong>LinearGradient</strong></h2>    <p>设置线性渐变效果,有两个构造函数</p>    <pre>  <code class="language-java">//坐标(x0,y0)渐变直线的起点,坐标(x1,y1)渐变直线的终点,color0和color1分别表示了渐变的起始颜色和终止颜色,TileMode也有CLAMP 、REPEAT 和 MIRROR三个取值  LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)  LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)</code></pre>    <p>例子:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private Context mContext;       private Bitmap mBitmap;       private Shader mShader;         // 省略构造方法         private void init() {            mShader = new LinearGradient(0, 0, 500, 500, Color.BLUE, Color.GREEN,Shader.TileMode.CLAMP);            mPaint = new Paint();            mPaint.setAntiAlias(true);       }         @Override       protected void onDraw(Canvas canvas) {            mPaint.setShader(mBitmapShader);            canvas.drawCircle(500, 550, 400, mPaint);       }    }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/84d22e81ed2a7baf15141a94eae828a6.jpg"></p>    <p>设置REPEAT 和 MIRROR就不贴图片了,小伙伴们可以自己试试看看效果。</p>    <h2><strong>RadialGrdient</strong></h2>    <p>设置光束从中心向四周发散的辐射渐变效果,构造方法:</p>    <pre>  <code class="language-java">//坐标(centerX,centerY)中心点坐标,radius圆的半径,centerColor中心颜色,edgeColor圆的轮廓颜色,颜色逐渐从centerColor渐变到edgeColor,TileMode也有CLAMP 、REPEAT 和 MIRROR三个取值  RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode)  RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode)</code></pre>    <p>例子:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private Context mContext;       private Shader mShader;         // 省略构造方法         private void init() {            mShader = new RadialGradient(500, 500, 400, Color.BLUE, Color.GREEN, Shader.TileMode.CLAMP);            mPaint = new Paint();            mPaint.setAntiAlias(true);       }         @Override       protected void onDraw(Canvas canvas) {            mPaint.setShader(mBitmapShader);            canvas.drawCircle(500, 550, 400, mPaint);       }    }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c1e8bb0ae78c6f965971de9e2cef1c76.jpg"></p>    <p>设置REPEAT 和 MIRROR也不贴图片了。</p>    <h2><strong>SweepGradient</strong></h2>    <p>设置绕着某中心点进行360度旋转渐变效果,构造方法:</p>    <pre>  <code class="language-java">//坐标(cx,cy)决定了中心点的位置,会绕着该中心点进行360度旋转。color0表示的是起点的颜色,color1表示的是终点的颜色  SweepGradient(float cx, float cy, int color0, int color1)  //坐标(cx,cy)决定了中心点的位置,colors颜色数组,position取值范围为[0,1],0和1都表示3点钟位置,0.25表示6点钟位置,0.5表示9点钟位置,0.75表示12点钟位置,诸如此类  SweepGradient(float cx, float cy, int[] colors, float[] positions)</code></pre>    <p>例子:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private Context mContext;       private Shader mShader;         // 省略构造方法         private void init() {            mShader = new SweepGradient(500, 500, Color.BLUE, Color.GREEN);            mPaint = new Paint();            mPaint.setAntiAlias(true);       }         @Override       protected void onDraw(Canvas canvas) {            mPaint.setShader(mBitmapShader);            canvas.drawCircle(500, 550, 400, mPaint);       }    }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/80febe61919f579e16ee82bb653f37a9.jpg"></p>    <h2><strong>ComposeShader</strong></h2>    <p>混合,有两个构造函数</p>    <pre>  <code class="language-java">//shaderA对应下层图形,shaderB对应上层图形  ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode)  ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode)</code></pre>    <p>例子:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private Context mContext;       private Bitmap mBitmap;       private Shader bitmapShader, linearGradient, composeShader;         // 省略构造方法         private void init() {            mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.logo);            bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);            linearGradient = new LinearGradient(0, 0, mBitmap.getWidth(), mBitmap.getHeight(), Color.BLUE, Color.GREEN, Shader.TileMode.CLAMP);            //bitmapShader对应下层图形,linearGradient对应上层图形,像素颜色混合采用MULTIPLY模式            composeShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.MULTIPLY);            mPaint = new Paint();            mPaint.setAntiAlias(true);       }         @Override       protected void onDraw(Canvas canvas) {            mPaint.setShader(mBitmapShader);            canvas.drawCircle(500, 550, 400, mPaint);       }  }</code></pre>    <p>效果如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0d0e0793bc6f167f7bc06778f46eed4a.jpg"></p>    <h2><strong>setShadowLayer</strong></h2>    <pre>  <code class="language-java">void setShadowLayer(float radius, float dx, float dy, int shadowColor)</code></pre>    <p>图形添加一个阴影层效果</p>    <h2><strong>setStrikeThruText</strong></h2>    <pre>  <code class="language-java">void setStrikeThruText (boolean strikeThruText)</code></pre>    <p>设置删除线</p>    <h2><strong>setStrokeCap</strong></h2>    <pre>  <code class="language-java">void setStrokeCap (Paint.Cap cap)</code></pre>    <p>当设置setStyle是Stroke或StrokeAndFill,设置笔刷的图形样式,如圆形样式Cap.ROUND或方形样式Cap.SQUARE</p>    <h2><strong>setStrokeJoin</strong></h2>    <pre>  <code class="language-java">void setStrokeJoin (Paint.Join join)</code></pre>    <p>当设置setStyle是Stroke或StrokeAndFill,设置绘制时各图形的结合方式,如影响矩形角的外轮廓</p>    <h2><strong>setStrokeMiter</strong></h2>    <pre>  <code class="language-java">void setStrokeMiter (float miter)</code></pre>    <p>当设置setStyle是Stroke或StrokeAndFill,设置斜切</p>    <h2><strong>setStrokeWidth</strong></h2>    <pre>  <code class="language-java">void setStrokeWidth (float width)</code></pre>    <p>当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度</p>    <h2><strong>setStyle</strong></h2>    <pre>  <code class="language-java">void setStyle (Paint.Style style)</code></pre>    <p>设置画笔样式,画笔样式分三种:</p>    <p>Paint.Style.STROKE:描边</p>    <p>Paint.Style.FILL_AND_STROKE:描边并填充</p>    <p>Paint.Style.FILL:填充</p>    <h2><strong>setSubpixelText</strong></h2>    <pre>  <code class="language-java">void setSubpixelText (boolean subpixelText)</code></pre>    <p>有助于文本在LCD屏幕上的显示效果</p>    <h2><strong>setTextAlign</strong></h2>    <pre>  <code class="language-java">void setTextAlign(Paint.Align align)</code></pre>    <p>设置文本对齐</p>    <h2><strong>setTextScaleX</strong></h2>    <pre>  <code class="language-java">void setTextScaleX(float scaleX)</code></pre>    <p>设置文本缩放倍数,1.0f为原始</p>    <h2><strong>setTextSize</strong></h2>    <pre>  <code class="language-java">void setTextSize(float textSize)</code></pre>    <p>设置字体大小</p>    <h2><strong>setTextSkewX</strong></h2>    <pre>  <code class="language-java">void setTextSkewX (float skewX)</code></pre>    <p>设置斜体文字,skewX为倾斜弧度,默认值0,大于0,向左斜,小于0,向右斜</p>    <h2><strong>setTypeface</strong></h2>    <pre>  <code class="language-java">Typeface  setTypeface(Typeface typeface)</code></pre>    <p>设置字体,Typeface包含了字体的类型,粗细,还有倾斜、颜色等。</p>    <pre>  <code class="language-java">mPaint.setTypeface(Typeface.SANS_SERIF);</code></pre>    <h2><strong>setUnderlineText</strong></h2>    <pre>  <code class="language-java">void setUnderlineText(boolean underlineText)</code></pre>    <p>设置下划线</p>    <h2><strong>setXfermode</strong></h2>    <pre>  <code class="language-java">Xfermode setXfermode (Xfermode xfermode)</code></pre>    <p>设置图像混合模式, Xfermode 有个子类去实现PorterDuffXfermode</p>    <h2><strong>PorterDuffXfermode</strong></h2>    <p>构造方法 PorterDuffXfermode(PorterDuff.Mode mode) ,参数就是上面的提到的,图形混合模式如图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ecc59255a3acf879894298af1374de31.png"></p>    <p>Dst:先画(下层)的图形;Src:后画(上层)的图形,然而被网上这张图片误导了,解释见 <a href="/misc/goto?guid=4959722862850817094" rel="nofollow,noindex">孙群博客</a> ,他也给了最终运行效果:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d3dd2c15706d2d144962ea892ba15e73.jpg"></p>    <p>我一一运行确实是如此,这里贴出Mode 为Screen代码:</p>    <pre>  <code class="language-java">public class PaintCanvas extends View {       private Paint mPaint;       private PorterDuffXfermode porterDuffXfermode;// 图形混合模式       private Context mContext;       private Bitmap mBitmap;       //省略构造方法         private void init() {           mBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.logo);           mPaint = new Paint();           mPaint.setAntiAlias(true);           // 实例化混合模式           porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SCREEN);       }        @Override      protected void onDraw(Canvas canvas) {           int canvasWidth = canvas.getWidth();           int canvasHeight = canvas.getHeight();           //新建一个layer,放置在canvas默认layer的上部,产生的layer初始时是完全透明的           int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);           //dst是先画的图形           canvas.drawBitmap(mBitmap, 0, 0, mPaint);           //设置混合模式           mPaint.setXfermode(porterDuffXfermode);           //src是后画的图形           mPaint.setColor(0xFFFFCC44);           canvas.drawCircle(600, 600, 200, mPaint);           //还原混合模式           mPaint.setXfermode(null);           //或canvas.restore()把这个layer绘制到canvas默认的layer上去           canvas.restoreToCount(layerId);      }    }</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c8851551aa1df285e1d0a6daecd2734d.jpg"></p>    <p> </p>    <h2>最后</h2>    <p>这篇文章真长,从开始写到最后的校对,花了很长时间,每段代码运行都截图上传。只能说实践是检验真理的唯一标准,不一定知道每个原理,都必须知道每个是什么样子的效果,记录完成方便自己日后查找,也方便大家哦,如果您能读到这篇文章的话。</p>    <p> </p>    <p>来自:http://www.androidchina.net/5406.html</p>    <p> </p>    
 本文由用户 windows7 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1477882828066.html
Bitmap 安卓开发 Android开发 移动开发