您的位置:首页 > 其它

利用PorterDuff.Mode做橡皮擦效果

2013-05-31 17:38 246 查看



http://stackoverflow.com/questions/3467334/erase-bitmap-parts-using-porterduff-mode 

假如我有一张背景图片, 

在背景图片上覆盖绘制了一层半透明的绿色 

当我们用手指涂抹屏幕的时候,手指涂抹过的地方绿色就被擦除,露出下面原先被遮挡住的背景图片 

1.利用canvas的drawPath做擦除效果。 

效果如下: 


 

实现代码: 

Java代码  


import android.app.Activity;  

import android.content.Context;  

import android.graphics.Bitmap;  

import android.graphics.BitmapFactory;  

import android.graphics.Canvas;  

import android.graphics.Paint;  

import android.graphics.Path;  

import android.graphics.PorterDuff;  

import android.graphics.PorterDuffXfermode;  

import android.graphics.Bitmap.Config;  

import android.os.Bundle;  

import android.util.DisplayMetrics;  

import android.view.MotionEvent;  

import android.view.View;  

  

public class Eraser_Use_drawPath extends Activity {  

  

    private int SCREEN_W;  

  

    private int SCREEN_H;  

  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(new MyView(this));  

  

    }  

  

    class MyView extends View {  

        private Bitmap mBitmap;  

        private Canvas mCanvas;  

        private Paint mPaint;  

        private Path  mPath;  

        private float mX, mY;  

        private static final float TOUCH_TOLERANCE = 4;  

          

        public MyView(Context context) {  

            super(context);  

            setFocusable(true);  

            setScreenWH();  

            setBackGround();  

              

            // 1.if cover is a image,you can open MENU_ITEM_COMMENT bellow  

            //Bitmap bm = createBitmapFromSRC();  

            // if you want to set cover image's alpha,you can open MENU_ITEM_COMMENT bellow  

            //bm = setBitmapAlpha(bm, 100);  

            // if you want to scale cover image,you can open MENU_ITEM_COMMENT bellow  

            //bm = scaleBitmapFillScreen(bm);  

  

            // 2.if cover is color  

            Bitmap bm = createBitmapFromARGB(0x8800ff00, SCREEN_W, SCREEN_H);  

            setCoverBitmap(bm);  

  

        }  

  

        private void setScreenWH() {  

            // get screen info  

            DisplayMetrics dm = new DisplayMetrics();  

            dm = this.getResources().getDisplayMetrics();  

            // get screen width  

            int screenWidth = dm.widthPixels;  

            // get screen height  

            int screenHeight = dm.heightPixels;  

  

            SCREEN_W = screenWidth;  

            SCREEN_H = screenHeight;  

        }  

  

        private Bitmap createBitmapFromSRC() {  

            return BitmapFactory.decodeResource(getResources(),  

                                                R.drawable.cover);  

        }  

  

        /** 

         *  

         * @param colorARGB should like 0x8800ff00 

         * @param width 

         * @param height 

         * @return 

         */  

        private Bitmap createBitmapFromARGB(int colorARGB, int width, int height) {  

            int[] argb = new int[width * height];  

  

            for (int i = 0; i < argb.length; i++) {  

  

                argb[i] = colorARGB;  

  

            }  

            return Bitmap.createBitmap(argb, width, height, Config.ARGB_8888);  

        }  

  

        /** 

         *  

         * @param bm 

         * @param alpha ,and alpha should be like ox00000000-oxff000000 

         * @note set bitmap's alpha 

         * @return 

         */  

       /* private Bitmap setBitmapAlpha(Bitmap bm, int alpha) { 

            int[] argb = new int[bm.getWidth() * bm.getHeight()]; 

            bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm 

                    .getHeight()); 

 

 

            for (int i = 0; i < argb.length; i++) { 

 

                argb[i] = ((alpha) | (argb[i] & 0x00FFFFFF)); 

            } 

            return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(), 

                                       Config.ARGB_8888); 

        }*/  

          

        /** 

         *  

         * @param bm 

         * @param alpha ,alpha should be between 0 and 255 

         * @note set bitmap's alpha 

         * @return 

         */  

        private Bitmap setBitmapAlpha(Bitmap bm, int alpha) {  

            int[] argb = new int[bm.getWidth() * bm.getHeight()];  

            bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm  

                    .getHeight());  

  

            for (int i = 0; i < argb.length; i++) {  

  

                argb[i] = ((alpha << 24) | (argb[i] & 0x00FFFFFF));  

            }  

            return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(),  

                                       Config.ARGB_8888);  

        }  

          

        /** 

         *  

         * @param bm 

         * @note if bitmap is smaller than screen, you can scale it fill the screen. 

         * @return  

         */  

        private Bitmap scaleBitmapFillScreen(Bitmap bm) {  

            return Bitmap.createScaledBitmap(bm, SCREEN_W, SCREEN_H, true);  

        }  

  

          

        private void setBackGround() {  

            setBackgroundResource(R.drawable.background);  

        }  

  

        /** 

         *  

         * @param bm 

         * @note set cover bitmap , which  overlay on background.  

         */  

        private void setCoverBitmap(Bitmap bm) {  

            // setting paint  

            mPaint = new Paint();  

            mPaint.setAlpha(0);  

            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));  

            mPaint.setAntiAlias(true);  

              

            mPaint.setDither(true);  

            mPaint.setStyle(Paint.Style.STROKE);  

            mPaint.setStrokeJoin(Paint.Join.ROUND);  

            mPaint.setStrokeCap(Paint.Cap.ROUND);  

            mPaint.setStrokeWidth(20);  

              

            //set path  

            mPath =  new Path();;  

  

            // converting bitmap into mutable bitmap  

            mBitmap = Bitmap.createBitmap(SCREEN_W, SCREEN_H, Config.ARGB_8888);  

            mCanvas = new Canvas();  

            mCanvas.setBitmap(mBitmap);  

            // drawXY will result on that Bitmap  

            // be sure parameter is bm, not mBitmap  

            mCanvas.drawBitmap(bm, 0, 0, null);  

        }  

  

         

  

        @Override  

        protected void onDraw(Canvas canvas) {  

            canvas.drawBitmap(mBitmap, 0, 0, null);  

            mCanvas.drawPath(mPath, mPaint);  

            super.onDraw(canvas);  

        }  

          

        private void touch_start(float x, float y) {  

            mPath.reset();  

            mPath.moveTo(x, y);  

            mX = x;  

            mY = y;  

        }  

        private void touch_move(float x, float y) {  

            float dx = Math.abs(x - mX);  

            float dy = Math.abs(y - mY);  

            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {  

                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);  

                mX = x;  

                mY = y;  

            }  

        }  

        private void touch_up() {  

            mPath.lineTo(mX, mY);  

            // commit the path to our offscreen  

            mCanvas.drawPath(mPath, mPaint);  

            // kill this so we don't double draw  

            mPath.reset();  

        }  

          

        @Override  

        public boolean onTouchEvent(MotionEvent event) {  

            float x = event.getX();  

            float y = event.getY();  

              

            switch (event.getAction()) {  

                case MotionEvent.ACTION_DOWN:  

                    touch_start(x, y);  

                    invalidate();  

                    break;  

                case MotionEvent.ACTION_MOVE:  

                    touch_move(x, y);  

                    invalidate();  

                    break;  

                case MotionEvent.ACTION_UP:  

                    touch_up();  

                    invalidate();  

                    break;  

            }  

            return true;  

        }  

    }  

}  

2.利用canvas的drawCircle做擦除效果 

效果如下: 


 

实现代码: 

Java代码  


package aliusa.cn;  

  

import android.app.Activity;  

import android.content.Context;  

import android.graphics.Bitmap;  

import android.graphics.BitmapFactory;  

import android.graphics.Canvas;  

import android.graphics.Paint;  

import android.graphics.PorterDuff;  

import android.graphics.PorterDuffXfermode;  

import android.graphics.Bitmap.Config;  

import android.os.Bundle;  

import android.util.DisplayMetrics;  

import android.view.MotionEvent;  

import android.view.View;  

  

public class Eraser_Use_drawCircle extends Activity {  

  

    private int SCREEN_W;  

  

    private int SCREEN_H;  

  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(new MyView(this));  

  

    }  

  

    class MyView extends View {  

        private Bitmap mBitmap;  

        private Canvas mCanvas;  

        private Paint mPaint;  

        int x = 0;  

  

        int y = 0;  

  

        int r = 0;  

          

        public MyView(Context context) {  

            super(context);  

            setFocusable(true);  

            setScreenWH();  

            setBackGround();  

              

            // 1.if cover is a image,you can open MENU_ITEM_COMMENT bellow  

            Bitmap bm = createBitmapFromSRC();  

            // if you want to set cover image's alpha,you can open MENU_ITEM_COMMENT bellow  

            bm = setBitmapAlpha(bm, 100);  

            // if you want to scale cover image,you can open MENU_ITEM_COMMENT bellow  

            bm = scaleBitmapFillScreen(bm);  

  

            // 2.if cover is color  

            //Bitmap bm = createBitmapFromARGB(0x8800ff00, SCREEN_W, SCREEN_H);  

            setCoverBitmap(bm);  

  

        }  

  

        private void setScreenWH() {  

            // get screen info  

            DisplayMetrics dm = new DisplayMetrics();  

            dm = this.getResources().getDisplayMetrics();  

            // get screen width  

            int screenWidth = dm.widthPixels;  

            // get screen height  

            int screenHeight = dm.heightPixels;  

  

            SCREEN_W = screenWidth;  

            SCREEN_H = screenHeight;  

        }  

  

        private Bitmap createBitmapFromSRC() {  

            return BitmapFactory.decodeResource(getResources(),  

                                                R.drawable.cover);  

        }  

  

        /** 

         *  

         * @param colorARGB should like 0x8800ff00 

         * @param width 

         * @param height 

         * @return 

         */  

        private Bitmap createBitmapFromARGB(int colorARGB, int width, int height) {  

            int[] argb = new int[width * height];  

  

            for (int i = 0; i < argb.length; i++) {  

  

                argb[i] = colorARGB;  

  

            }  

            return Bitmap.createBitmap(argb, width, height, Config.ARGB_8888);  

        }  

  

        /** 

         *  

         * @param bm 

         * @param alpha ,and alpha should be like ox00000000-oxff000000 

         * @note set bitmap's alpha 

         * @return 

         */  

       /* private Bitmap setBitmapAlpha(Bitmap bm, int alpha) { 

            int[] argb = new int[bm.getWidth() * bm.getHeight()]; 

            bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm 

                    .getHeight()); 

 

 

            for (int i = 0; i < argb.length; i++) { 

 

                argb[i] = ((alpha) | (argb[i] & 0x00FFFFFF)); 

            } 

            return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(), 

                                       Config.ARGB_8888); 

        }*/  

          

        /** 

         *  

         * @param bm 

         * @param alpha ,alpha should be between 0 and 255 

         * @note set bitmap's alpha 

         * @return 

         */  

        private Bitmap setBitmapAlpha(Bitmap bm, int alpha) {  

            int[] argb = new int[bm.getWidth() * bm.getHeight()];  

            bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm  

                    .getHeight());  

  

            for (int i = 0; i < argb.length; i++) {  

  

                argb[i] = ((alpha << 24) | (argb[i] & 0x00FFFFFF));  

            }  

            return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(),  

                                       Config.ARGB_8888);  

        }  

          

        /** 

         *  

         * @param bm 

         * @note if bitmap is smaller than screen, you can scale it fill the screen. 

         * @return  

         */  

        private Bitmap scaleBitmapFillScreen(Bitmap bm) {  

            return Bitmap.createScaledBitmap(bm, SCREEN_W, SCREEN_H, true);  

        }  

  

          

        private void setBackGround() {  

            setBackgroundResource(R.drawable.background);  

        }  

  

        /** 

         *  

         * @param bm 

         * @note set cover bitmap , which  overlay on background.  

         */  

        private void setCoverBitmap(Bitmap bm) {  

            // setting paint  

            mPaint = new Paint();  

            mPaint.setAlpha(0);  

            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));  

            mPaint.setAntiAlias(true);  

  

            // converting bitmap into mutable bitmap  

            mBitmap = Bitmap.createBitmap(SCREEN_W, SCREEN_H, Config.ARGB_8888);  

            mCanvas = new Canvas();  

            mCanvas.setBitmap(mBitmap);  

            // drawXY will result on that Bitmap  

            // be sure parameter is bm, not mBitmap  

            mCanvas.drawBitmap(bm, 0, 0, null);  

        }  

  

         

  

        @Override  

        protected void onDraw(Canvas canvas) {  

         // draw a circle that is erasing bitmap  

            mCanvas.drawCircle(x, y, r, mPaint);  

            canvas.drawBitmap(mBitmap, 0, 0, null);  

            super.onDraw(canvas);  

        }  

          

        @Override  

        public boolean onTouchEvent(MotionEvent event) {  

            // set parameter to draw circle on touch event  

            x = (int) event.getX();  

            y = (int) event.getY();  

            r = 20;  

            // Atlast invalidate canvas  

            invalidate();  

            return true;  

        }  

    }  

擦除效果代码.zip (295.2 KB)
下载次数: 300
查看图片附件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: