利用PorterDuff.Mode做橡皮擦效果
2013-05-31 17:38
246 查看
假如我有一张背景图片,
在背景图片上覆盖绘制了一层半透明的绿色
当我们用手指涂抹屏幕的时候,手指涂抹过的地方绿色就被擦除,露出下面原先被遮挡住的背景图片
1.利用canvas的drawPath做擦除效果。
效果如下:
![](http://dl.iteye.com/upload/attachment/453241/e72f8d4b-562e-3fb5-a8ea-12feb7afe0aa.png)
实现代码:
Java代码
![](http://aliusa.iteye.com/images/icon_star.png)
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做擦除效果
效果如下:
![](http://dl.iteye.com/upload/attachment/453245/08df02ba-e300-3bdf-9f27-1f57964f01ac.png)
实现代码:
Java代码
![](http://aliusa.iteye.com/images/icon_star.png)
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
查看图片附件
相关文章推荐
- 利用PorterDuff.Mode做橡皮擦效果
- PorterDuffXfermode实现Android刮刮卡效果
- PorterDuffXfermode ——实现刮刮卡效果
- 关于PorterDuffXferMode效果出不来的问题
- Android 自定义View之PorterDuffXfermode的使用(刮刮卡的效果实现)
- 利用PorterDuffXfermode 对Bitmap的特殊处理
- PorterDuff.Mode 效果
- 使用PorterDuffXfermode画出刮刮奖效果p146-p148
- 利用 2D 图形和 PorterDuffXferMode 等实现被遮罩的图片
- 关于使用PorterDuff.Mode.CLEAR实现丧心病狂的高亮效果
- 自定义View通过PorterDuffXfermode实现图片遮罩效果
- PorterDuffXfermode 实现刮刮卡效果
- 使用PorterDuffXfermode实现橡皮檫效果(可实现Showcase效果)
- android之刮刮卡中奖效果PorterDuffXfermode与paint属性详解
- 自定义控件(6)---PorterDuffXfermode图形过滤器之橡皮擦应用
- [转]Android PorterDuff.Mode效果
- 微信底部导航渐变效果-----viewpager&PorterDuffXfermode
- Android使用PorterDuffXfermode实现遮罩效果
- PorterDuffXfermode实现刮刮卡效果
- PorterDuff.Mode与Xfermode(android 6.0)