zoukankan      html  css  js  c++  java
  • android Xfermode PorterDuffXfermode 实现遮罩层

    参考:

    http://www.cnblogs.com/jacktu/archive/2012/01/02/2310326.html

    http://blog.csdn.net/yun90/article/details/8618521

    基础知识:

    1.下面的Xfermode子类可以改变这种行为:

    AvoidXfermode  指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

    PixelXorXfermode  当覆盖已有的颜色时,应用一个简单的像素XOR操作。

    PorterDuffXfermode  这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

    要应用转换模式,可以使用setXferMode方法,如下所示:

    AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID);    borderPen.setXfermode(avoid);

    2.Porter-Duff 效果图:

    3.16条Porter-Duff规则

    1.PorterDuff.Mode.CLEAR

       所绘制不会提交到画布上。
    2.PorterDuff.Mode.SRC

       显示上层绘制图片
    3.PorterDuff.Mode.DST

      显示下层绘制图片
    4.PorterDuff.Mode.SRC_OVER

      正常绘制显示,上下层绘制叠盖。
    5.PorterDuff.Mode.DST_OVER

      上下层都显示。下层居上显示。
    6.PorterDuff.Mode.SRC_IN

       取两层绘制交集。显示上层。
    7.PorterDuff.Mode.DST_IN

      取两层绘制交集。显示下层。
    8.PorterDuff.Mode.SRC_OUT

     取上层绘制非交集部分。
    9.PorterDuff.Mode.DST_OUT

     取下层绘制非交集部分。
    10.PorterDuff.Mode.SRC_ATOP

     取下层非交集部分与上层交集部分
    11.PorterDuff.Mode.DST_ATOP

      取上层非交集部分与下层交集部分
    12.PorterDuff.Mode.XOR

      
    13.PorterDuff.Mode.DARKEN


    14.PorterDuff.Mode.LIGHTEN


    15.PorterDuff.Mode.MULTIPLY


    16.PorterDuff.Mode.SCREEN

    实例1:

    首先用图片处理软件制作一个和中间黄色区域相同的图形,我们将在代码中设置它做为遮罩。

     mast 图

    View的draw方法

    public void draw(Canvas canvas) {  
            //背景部分,也就是上面的图形  
            Bitmap background = BitmapFactory.decodeResource(getResources(),  
                    R.drawable.guage);  
            //遮罩,就是提取来部分  
            Bitmap mask = BitmapFactory.decodeResource(getResources(),  
                    R.drawable.mask);  
              
            canvas.drawColor(Color.WHITE);  
            canvas.drawBitmap(background, 0, 0, null);  
            Paint paint = new Paint();  
            paint.setFilterBitmap(false);  
      
            int x = 0;  
            int y = 0;  
      
            // draw the src/dst example into our offscreen bitmap  
            int sc = canvas.saveLayer(x, y, x + background.getWidth(), y + background.getHeight(), null,  
                    Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG  
                            | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG  
                            | Canvas.FULL_COLOR_LAYER_SAVE_FLAG  
                            | Canvas.CLIP_TO_LAYER_SAVE_FLAG);  
            // canvas.drawBitmap(mDstB, 0, 0, paint);  
            canvas.drawRect(0, 0, background.getWidth() / 2, background  
                    .getHeight(), paint);  
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  
            // canvas.drawBitmap(mSrcB, 0, 0, paint);  
            canvas.drawBitmap(mask, 0f, 0f, paint);  
            paint.setXfermode(null);  
            canvas.restoreToCount(sc);  
      
        }  

    只用控制绘制的矩形的长度就可以实现进度条的效果了。


                 

    实例2

    launcher程序中将icon设置为圆角形状

    package com.example.testsurfaceview;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PorterDuff.Mode;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.graphics.drawable.PaintDrawable;
    import android.util.AttributeSet;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    
    @SuppressLint("NewApi")
    public class CustomSurfaceView extends SurfaceView implements Callback {
    
        public CustomSurfaceView(Context context, AttributeSet attrs,
                int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init();
        }
    
        public CustomSurfaceView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        public CustomSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public CustomSurfaceView(Context context) {
            super(context);
            init();
        }
    
        private void init() {
            this.getHolder().addCallback(this);
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            Canvas canvas = getHolder().lockCanvas();
            canvas.drawColor(Color.WHITE);
    
            int w = canvas.getWidth();
            int h = canvas.getHeight();
    
            Bitmap bitmap = this.getIcon(this.getContext());
            
            Bitmap mat = BitmapFactory.decodeResource(this.getResources(), R.drawable.default_icon_mask);
    
            bitmap = this.composeMat(this.getContext(), bitmap, mat);
            
            int left = (w - bitmap.getWidth()) / 2;
            int top = (h - bitmap.getHeight()) / 2;
    
            canvas.drawBitmap(bitmap, left, top, new Paint());
    
            getHolder().unlockCanvasAndPost(canvas);
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
    
        }
    
        private Bitmap getIcon(Context mContext) {
            int wh = (int) mContext.getResources().getDimension(R.dimen.icon_wh);
            int width = wh;
            int height = wh;
            Drawable icon = mContext.getResources().getDrawable(
                    R.drawable.ic_launcher);
    
            if (icon instanceof PaintDrawable) {
                PaintDrawable painter = (PaintDrawable) icon;
                painter.setIntrinsicWidth(width);
                painter.setIntrinsicHeight(height);
            } else if (icon instanceof BitmapDrawable) {
                // Ensure the bitmap has a density.
                BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
                Bitmap bitmap = bitmapDrawable.getBitmap();
                if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
                    bitmapDrawable.setTargetDensity(mContext.getResources()
                            .getDisplayMetrics());
                }
            }
            int sourceWidth = icon.getIntrinsicWidth();
            int sourceHeight = icon.getIntrinsicHeight();
    
            if (sourceWidth > 0 && sourceHeight > 0) {
                // There are intrinsic sizes.
                if (wh < sourceWidth || wh < sourceHeight) {
                    // It's too big, scale it down.
                    final float ratio = (float) sourceWidth / sourceHeight;
                    if (sourceWidth > sourceHeight) {
                        height = (int) (width / ratio);
                    } else if (sourceHeight > sourceWidth) {
                        width = (int) (height * ratio);
                    }
                } else if (sourceWidth < width && sourceHeight < height) {
                    // Don't scale up the icon
                    width = sourceWidth;
                    height = sourceHeight;
                }
            }
            int textureWidth = wh;
            int textureHeight = wh;
            final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
                    Bitmap.Config.ARGB_8888);
            Canvas sCanvas = new Canvas();
            sCanvas.setBitmap(bitmap);
            sCanvas.drawColor(Color.GRAY);
    
            final int left = (textureWidth - width) / 2;
            final int top = (textureHeight - height) / 2;
            icon.setBounds(left, top, left + width, top + height);
    
            Rect sOldBounds = new Rect();
            sOldBounds.set(icon.getBounds());
            icon.setBounds(left, top, left + width, top + height);
            icon.draw(sCanvas);
            icon.setBounds(sOldBounds);
            sCanvas.setBitmap(null);
    
            return bitmap;
        }
    
        private static final Paint sThemePaint2 = new Paint();
        private static final android.graphics.Xfermode Xfermode_DST_IN = new PorterDuffXfermode(
                Mode.DST_IN);
        private static final android.graphics.Xfermode Xfermode_SRC_IN = new PorterDuffXfermode(
                Mode.SRC_IN);
    
        private Bitmap composeMat(Context context, Bitmap src, Bitmap mat) {
            int sIconWidth = mat.getWidth();
            int sIconHeight = mat.getHeight();
            final Bitmap base = Bitmap.createBitmap(sIconWidth, sIconHeight,
                    Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(base);
            sThemePaint2.setXfermode(null);
    //        canvas.drawRect(new Rect(0, 0, sIconWidth, sIconHeight), sThemePaint2);
    //        sThemePaint2.setXfermode(Xfermode_SRC_IN);
            canvas.drawBitmap(mat, (sIconWidth-mat.getWidth())/2, (sIconHeight-mat.getHeight())/2, sThemePaint2);
            sThemePaint2.setXfermode(Xfermode_SRC_IN);        
            canvas.drawBitmap(src, ((sIconWidth-src.getWidth())/2), (sIconHeight-src.getHeight())/2, sThemePaint2);
            sThemePaint2.setXfermode(null);
    
            return base;
        }
    
    }

     

  • 相关阅读:
    MySQL数据库小结
    使用Python操作MySQL数据库
    MySQL索引原理
    MySQL性能分析之Explain
    201907 TIOBE 编程语言排行榜-Python坐稳第三
    MySQL索引的数据结构-B+树介绍
    MySQL多表查询综合练习答案
    MySQL记录操作
    MySQL多表查询
    javascript实现无缝上下滚动(转)
  • 原文地址:https://www.cnblogs.com/wjw334/p/4345217.html
Copyright © 2011-2022 走看看