利用PorterDuff.Mode做橡皮擦效果

http://stackoverflow.com/questions/3467334/erase-bitmap-parts-using-porterduff-mode 
假如我有一张背景图片, 
在背景图片上覆盖绘制了一层半透明的绿色 
当我们用手指涂抹屏幕的时候,手指涂抹过的地方绿色就被擦除,露出下面原先被遮挡住的背景图片 
1.利用canvas的drawPath做擦除效果。 
效果如下: 

 

实现代码: 
Java代码   收藏代码
  1. import android.app.Activity;  
  2. import android.content.Context;  
  3. import android.graphics.Bitmap;  
  4. import android.graphics.BitmapFactory;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Paint;  
  7. import android.graphics.Path;  
  8. import android.graphics.PorterDuff;  
  9. import android.graphics.PorterDuffXfermode;  
  10. import android.graphics.Bitmap.Config;  
  11. import android.os.Bundle;  
  12. import android.util.DisplayMetrics;  
  13. import android.view.MotionEvent;  
  14. import android.view.View;  
  15.   
  16. public class Eraser_Use_drawPath extends Activity {  
  17.   
  18.     private int SCREEN_W;  
  19.   
  20.     private int SCREEN_H;  
  21.   
  22.     @Override  
  23.     protected void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(new MyView(this));  
  26.   
  27.     }  
  28.   
  29.     class MyView extends View {  
  30.         private Bitmap mBitmap;  
  31.         private Canvas mCanvas;  
  32.         private Paint mPaint;  
  33.         private Path  mPath;  
  34.         private float mX, mY;  
  35.         private static final float TOUCH_TOLERANCE = 4;  
  36.           
  37.         public MyView(Context context) {  
  38.             super(context);  
  39.             setFocusable(true);  
  40.             setScreenWH();  
  41.             setBackGround();  
  42.               
  43.             // 1.if cover is a image,you can open MENU_ITEM_COMMENT bellow  
  44.             //Bitmap bm = createBitmapFromSRC();  
  45.             // if you want to set cover image's alpha,you can open MENU_ITEM_COMMENT bellow  
  46.             //bm = setBitmapAlpha(bm, 100);  
  47.             // if you want to scale cover image,you can open MENU_ITEM_COMMENT bellow  
  48.             //bm = scaleBitmapFillScreen(bm);  
  49.   
  50.             // 2.if cover is color  
  51.             Bitmap bm = createBitmapFromARGB(0x8800ff00, SCREEN_W, SCREEN_H);  
  52.             setCoverBitmap(bm);  
  53.   
  54.         }  
  55.   
  56.         private void setScreenWH() {  
  57.             // get screen info  
  58.             DisplayMetrics dm = new DisplayMetrics();  
  59.             dm = this.getResources().getDisplayMetrics();  
  60.             // get screen width  
  61.             int screenWidth = dm.widthPixels;  
  62.             // get screen height  
  63.             int screenHeight = dm.heightPixels;  
  64.   
  65.             SCREEN_W = screenWidth;  
  66.             SCREEN_H = screenHeight;  
  67.         }  
  68.   
  69.         private Bitmap createBitmapFromSRC() {  
  70.             return BitmapFactory.decodeResource(getResources(),  
  71.                                                 R.drawable.cover);  
  72.         }  
  73.   
  74.         /** 
  75.          *  
  76.          * @param colorARGB should like 0x8800ff00 
  77.          * @param width 
  78.          * @param height 
  79.          * @return 
  80.          */  
  81.         private Bitmap createBitmapFromARGB(int colorARGB, int width, int height) {  
  82.             int[] argb = new int[width * height];  
  83.   
  84.             for (int i = 0; i < argb.length; i++) {  
  85.   
  86.                 argb[i] = colorARGB;  
  87.   
  88.             }  
  89.             return Bitmap.createBitmap(argb, width, height, Config.ARGB_8888);  
  90.         }  
  91.   
  92.         /** 
  93.          *  
  94.          * @param bm 
  95.          * @param alpha ,and alpha should be like ox00000000-oxff000000 
  96.          * @note set bitmap's alpha 
  97.          * @return 
  98.          */  
  99.        /* private Bitmap setBitmapAlpha(Bitmap bm, int alpha) { 
  100.             int[] argb = new int[bm.getWidth() * bm.getHeight()]; 
  101.             bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm 
  102.                     .getHeight()); 
  103.  
  104.  
  105.             for (int i = 0; i < argb.length; i++) { 
  106.  
  107.                 argb[i] = ((alpha) | (argb[i] & 0x00FFFFFF)); 
  108.             } 
  109.             return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(), 
  110.                                        Config.ARGB_8888); 
  111.         }*/  
  112.           
  113.         /** 
  114.          *  
  115.          * @param bm 
  116.          * @param alpha ,alpha should be between 0 and 255 
  117.          * @note set bitmap's alpha 
  118.          * @return 
  119.          */  
  120.         private Bitmap setBitmapAlpha(Bitmap bm, int alpha) {  
  121.             int[] argb = new int[bm.getWidth() * bm.getHeight()];  
  122.             bm.getPixels(argb, 0, bm.getWidth(), 00, bm.getWidth(), bm  
  123.                     .getHeight());  
  124.   
  125.             for (int i = 0; i < argb.length; i++) {  
  126.   
  127.                 argb[i] = ((alpha << 24) | (argb[i] & 0x00FFFFFF));  
  128.             }  
  129.             return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(),  
  130.                                        Config.ARGB_8888);  
  131.         }  
  132.           
  133.         /** 
  134.          *  
  135.          * @param bm 
  136.          * @note if bitmap is smaller than screen, you can scale it fill the screen. 
  137.          * @return  
  138.          */  
  139.         private Bitmap scaleBitmapFillScreen(Bitmap bm) {  
  140.             return Bitmap.createScaledBitmap(bm, SCREEN_W, SCREEN_H, true);  
  141.         }  
  142.   
  143.           
  144.         private void setBackGround() {  
  145.             setBackgroundResource(R.drawable.background);  
  146.         }  
  147.   
  148.         /** 
  149.          *  
  150.          * @param bm 
  151.          * @note set cover bitmap , which  overlay on background.  
  152.          */  
  153.         private void setCoverBitmap(Bitmap bm) {  
  154.             // setting paint  
  155.             mPaint = new Paint();  
  156.             mPaint.setAlpha(0);  
  157.             mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));  
  158.             mPaint.setAntiAlias(true);  
  159.               
  160.             mPaint.setDither(true);  
  161.             mPaint.setStyle(Paint.Style.STROKE);  
  162.             mPaint.setStrokeJoin(Paint.Join.ROUND);  
  163.             mPaint.setStrokeCap(Paint.Cap.ROUND);  
  164.             mPaint.setStrokeWidth(20);  
  165.               
  166.             //set path  
  167.             mPath =  new Path();;  
  168.   
  169.             // converting bitmap into mutable bitmap  
  170.             mBitmap = Bitmap.createBitmap(SCREEN_W, SCREEN_H, Config.ARGB_8888);  
  171.             mCanvas = new Canvas();  
  172.             mCanvas.setBitmap(mBitmap);  
  173.             // drawXY will result on that Bitmap  
  174.             // be sure parameter is bm, not mBitmap  
  175.             mCanvas.drawBitmap(bm, 00null);  
  176.         }  
  177.   
  178.          
  179.   
  180.         @Override  
  181.         protected void onDraw(Canvas canvas) {  
  182.             canvas.drawBitmap(mBitmap, 00null);  
  183.             mCanvas.drawPath(mPath, mPaint);  
  184.             super.onDraw(canvas);  
  185.         }  
  186.           
  187.         private void touch_start(float x, float y) {  
  188.             mPath.reset();  
  189.             mPath.moveTo(x, y);  
  190.             mX = x;  
  191.             mY = y;  
  192.         }  
  193.         private void touch_move(float x, float y) {  
  194.             float dx = Math.abs(x - mX);  
  195.             float dy = Math.abs(y - mY);  
  196.             if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {  
  197.                 mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);  
  198.                 mX = x;  
  199.                 mY = y;  
  200.             }  
  201.         }  
  202.         private void touch_up() {  
  203.             mPath.lineTo(mX, mY);  
  204.             // commit the path to our offscreen  
  205.             mCanvas.drawPath(mPath, mPaint);  
  206.             // kill this so we don't double draw  
  207.             mPath.reset();  
  208.         }  
  209.           
  210.         @Override  
  211.         public boolean onTouchEvent(MotionEvent event) {  
  212.             float x = event.getX();  
  213.             float y = event.getY();  
  214.               
  215.             switch (event.getAction()) {  
  216.                 case MotionEvent.ACTION_DOWN:  
  217.                     touch_start(x, y);  
  218.                     invalidate();  
  219.                     break;  
  220.                 case MotionEvent.ACTION_MOVE:  
  221.                     touch_move(x, y);  
  222.                     invalidate();  
  223.                     break;  
  224.                 case MotionEvent.ACTION_UP:  
  225.                     touch_up();  
  226.                     invalidate();  
  227.                     break;  
  228.             }  
  229.             return true;  
  230.         }  
  231.     }  
  232. }  


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

 

实现代码: 
Java代码   收藏代码
  1. package aliusa.cn;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapFactory;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Paint;  
  9. import android.graphics.PorterDuff;  
  10. import android.graphics.PorterDuffXfermode;  
  11. import android.graphics.Bitmap.Config;  
  12. import android.os.Bundle;  
  13. import android.util.DisplayMetrics;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16.   
  17. public class Eraser_Use_drawCircle extends Activity {  
  18.   
  19.     private int SCREEN_W;  
  20.   
  21.     private int SCREEN_H;  
  22.   
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(new MyView(this));  
  27.   
  28.     }  
  29.   
  30.     class MyView extends View {  
  31.         private Bitmap mBitmap;  
  32.         private Canvas mCanvas;  
  33.         private Paint mPaint;  
  34.         int x = 0;  
  35.   
  36.         int y = 0;  
  37.   
  38.         int r = 0;  
  39.           
  40.         public MyView(Context context) {  
  41.             super(context);  
  42.             setFocusable(true);  
  43.             setScreenWH();  
  44.             setBackGround();  
  45.               
  46.             // 1.if cover is a image,you can open MENU_ITEM_COMMENT bellow  
  47.             Bitmap bm = createBitmapFromSRC();  
  48.             // if you want to set cover image's alpha,you can open MENU_ITEM_COMMENT bellow  
  49.             bm = setBitmapAlpha(bm, 100);  
  50.             // if you want to scale cover image,you can open MENU_ITEM_COMMENT bellow  
  51.             bm = scaleBitmapFillScreen(bm);  
  52.   
  53.             // 2.if cover is color  
  54.             //Bitmap bm = createBitmapFromARGB(0x8800ff00, SCREEN_W, SCREEN_H);  
  55.             setCoverBitmap(bm);  
  56.   
  57.         }  
  58.   
  59.         private void setScreenWH() {  
  60.             // get screen info  
  61.             DisplayMetrics dm = new DisplayMetrics();  
  62.             dm = this.getResources().getDisplayMetrics();  
  63.             // get screen width  
  64.             int screenWidth = dm.widthPixels;  
  65.             // get screen height  
  66.             int screenHeight = dm.heightPixels;  
  67.   
  68.             SCREEN_W = screenWidth;  
  69.             SCREEN_H = screenHeight;  
  70.         }  
  71.   
  72.         private Bitmap createBitmapFromSRC() {  
  73.             return BitmapFactory.decodeResource(getResources(),  
  74.                                                 R.drawable.cover);  
  75.         }  
  76.   
  77.         /** 
  78.          *  
  79.          * @param colorARGB should like 0x8800ff00 
  80.          * @param width 
  81.          * @param height 
  82.          * @return 
  83.          */  
  84.         private Bitmap createBitmapFromARGB(int colorARGB, int width, int height) {  
  85.             int[] argb = new int[width * height];  
  86.   
  87.             for (int i = 0; i < argb.length; i++) {  
  88.   
  89.                 argb[i] = colorARGB;  
  90.   
  91.             }  
  92.             return Bitmap.createBitmap(argb, width, height, Config.ARGB_8888);  
  93.         }  
  94.   
  95.         /** 
  96.          *  
  97.          * @param bm 
  98.          * @param alpha ,and alpha should be like ox00000000-oxff000000 
  99.          * @note set bitmap's alpha 
  100.          * @return 
  101.          */  
  102.        /* private Bitmap setBitmapAlpha(Bitmap bm, int alpha) { 
  103.             int[] argb = new int[bm.getWidth() * bm.getHeight()]; 
  104.             bm.getPixels(argb, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm 
  105.                     .getHeight()); 
  106.  
  107.  
  108.             for (int i = 0; i < argb.length; i++) { 
  109.  
  110.                 argb[i] = ((alpha) | (argb[i] & 0x00FFFFFF)); 
  111.             } 
  112.             return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(), 
  113.                                        Config.ARGB_8888); 
  114.         }*/  
  115.           
  116.         /** 
  117.          *  
  118.          * @param bm 
  119.          * @param alpha ,alpha should be between 0 and 255 
  120.          * @note set bitmap's alpha 
  121.          * @return 
  122.          */  
  123.         private Bitmap setBitmapAlpha(Bitmap bm, int alpha) {  
  124.             int[] argb = new int[bm.getWidth() * bm.getHeight()];  
  125.             bm.getPixels(argb, 0, bm.getWidth(), 00, bm.getWidth(), bm  
  126.                     .getHeight());  
  127.   
  128.             for (int i = 0; i < argb.length; i++) {  
  129.   
  130.                 argb[i] = ((alpha << 24) | (argb[i] & 0x00FFFFFF));  
  131.             }  
  132.             return Bitmap.createBitmap(argb, bm.getWidth(), bm.getHeight(),  
  133.                                        Config.ARGB_8888);  
  134.         }  
  135.           
  136.         /** 
  137.          *  
  138.          * @param bm 
  139.          * @note if bitmap is smaller than screen, you can scale it fill the screen. 
  140.          * @return  
  141.          */  
  142.         private Bitmap scaleBitmapFillScreen(Bitmap bm) {  
  143.             return Bitmap.createScaledBitmap(bm, SCREEN_W, SCREEN_H, true);  
  144.         }  
  145.   
  146.           
  147.         private void setBackGround() {  
  148.             setBackgroundResource(R.drawable.background);  
  149.         }  
  150.   
  151.         /** 
  152.          *  
  153.          * @param bm 
  154.          * @note set cover bitmap , which  overlay on background.  
  155.          */  
  156.         private void setCoverBitmap(Bitmap bm) {  
  157.             // setting paint  
  158.             mPaint = new Paint();  
  159.             mPaint.setAlpha(0);  
  160.             mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));  
  161.             mPaint.setAntiAlias(true);  
  162.   
  163.             // converting bitmap into mutable bitmap  
  164.             mBitmap = Bitmap.createBitmap(SCREEN_W, SCREEN_H, Config.ARGB_8888);  
  165.             mCanvas = new Canvas();  
  166.             mCanvas.setBitmap(mBitmap);  
  167.             // drawXY will result on that Bitmap  
  168.             // be sure parameter is bm, not mBitmap  
  169.             mCanvas.drawBitmap(bm, 00null);  
  170.         }  
  171.   
  172.          
  173.   
  174.         @Override  
  175.         protected void onDraw(Canvas canvas) {  
  176.          // draw a circle that is erasing bitmap  
  177.             mCanvas.drawCircle(x, y, r, mPaint);  
  178.             canvas.drawBitmap(mBitmap, 00null);  
  179.             super.onDraw(canvas);  
  180.         }  
  181.           
  182.         @Override  
  183.         public boolean onTouchEvent(MotionEvent event) {  
  184.             // set parameter to draw circle on touch event  
  185.             x = (int) event.getX();  
  186.             y = (int) event.getY();  
  187.             r = 20;  
  188.             // Atlast invalidate canvas  
  189.             invalidate();  
  190.             return true;  
  191.         }  
  192.     }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值