利用PorterDuff.Mode做橡皮擦效果


 博客分类: 

 Android

AndroidOS

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

 

实现代码

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;  

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.利用canvasdrawCircle做擦除效果 
效果如下: 

 

实现代码: 

Java代码  

233 package aliusa.cn;  

234   

235 import android.app.Activity;  

236 import android.content.Context;  

237 import android.graphics.Bitmap;  

238 import android.graphics.BitmapFactory;  

239 import android.graphics.Canvas;  

240 import android.graphics.Paint;  

241 import android.graphics.PorterDuff;  

242 import android.graphics.PorterDuffXfermode;  

243 import android.graphics.Bitmap.Config;  

244 import android.os.Bundle;  

245 import android.util.DisplayMetrics;  

246 import android.view.MotionEvent;  

247 import android.view.View;  

248   

249 public class Eraser_Use_drawCircle extends Activity {  

250   

251     private int SCREEN_W;  

252   

253     private int SCREEN_H;  

254   

255     @Override  

256     protected void onCreate(Bundle savedInstanceState) {  

257         super.onCreate(savedInstanceState);  

258         setContentView(new MyView(this));  

259   

260     }  

261   

262     class MyView extends View {  

263         private Bitmap mBitmap;  

264         private Canvas mCanvas;  

265         private Paint mPaint;  

266         int x = 0;  

267   

268         int y = 0;  

269   

270         int r = 0;  

271           

272         public MyView(Context context) {  

273             super(context);  

274             setFocusable(true);  

275             setScreenWH();  

276             setBackGround();  

277               

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

279             Bitmap bm = createBitmapFromSRC();  

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

281             bm = setBitmapAlpha(bm, 100);  

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

283             bm = scaleBitmapFillScreen(bm);  

284   

285             // 2.if cover is color  

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

287             setCoverBitmap(bm);  

288   

289         }  

290   

291         private void setScreenWH() {  

292             // get screen info  

293             DisplayMetrics dm = new DisplayMetrics();  

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

295             // get screen width  

296             int screenWidth = dm.widthPixels;  

297             // get screen height  

298             int screenHeight = dm.heightPixels;  

299   

300             SCREEN_W = screenWidth;  

301             SCREEN_H = screenHeight;  

302         }  

303   

304         private Bitmap createBitmapFromSRC() {  

305             return BitmapFactory.decodeResource(getResources(),  

306                                                 R.drawable.cover);  

307         }  

308   

309         /** 

310          *  

311          * @param colorARGB should like 0x8800ff00 

312          * @param width 

313          * @param height 

314          * @return 

315          */  

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

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

318   

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

320   

321                 argb[i] = colorARGB;  

322   

323             }  

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

325         }  

326   

327         /** 

328          *  

329          * @param bm 

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

331          * @note set bitmap's alpha 

332          * @return 

333          */  

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

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

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

337                     .getHeight()); 

338  

339  

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

341  

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

343             } 

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

345                                        Config.ARGB_8888); 

346         }*/  

347           

348         /** 

349          *  

350          * @param bm 

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

352          * @note set bitmap's alpha 

353          * @return 

354          */  

355         private Bitmap setBitmapAlpha(Bitmap bm, int alpha) {  

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

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

358                     .getHeight());  

359   

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

361   

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

363             }  

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

365                                        Config.ARGB_8888);  

366         }  

367           

368         /** 

369          *  

370          * @param bm 

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

372          * @return  

373          */  

374         private Bitmap scaleBitmapFillScreen(Bitmap bm) {  

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

376         }  

377   

378           

379         private void setBackGround() {  

380             setBackgroundResource(R.drawable.background);  

381         }  

382   

383         /** 

384          *  

385          * @param bm 

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

387          */  

388         private void setCoverBitmap(Bitmap bm) {  

389             // setting paint  

390             mPaint = new Paint();  

391             mPaint.setAlpha(0);  

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

393             mPaint.setAntiAlias(true);  

394   

395             // converting bitmap into mutable bitmap  

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

397             mCanvas = new Canvas();  

398             mCanvas.setBitmap(mBitmap);  

399             // drawXY will result on that Bitmap  

400             // be sure parameter is bm, not mBitmap  

401             mCanvas.drawBitmap(bm, 00null);  

402         }  

403   

404          

405   

406         @Override  

407         protected void onDraw(Canvas canvas) {  

408          // draw a circle that is erasing bitmap  

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

410             canvas.drawBitmap(mBitmap, 00null);  

411             super.onDraw(canvas);  

412         }  

413           

414         @Override  

415         public boolean onTouchEvent(MotionEvent event) {  

416             // set parameter to draw circle on touch event  

417             x = (int) event.getX();  

418             y = (int) event.getY();  

419             r = 20;  

420             // Atlast invalidate canvas  

421             invalidate();  

422             return true;  

423         }  

424     }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值