安卓-橡皮擦擦线完整实现
小伙伴儿们来看看就好
因为公司的需要,我从网上找了很多demo,但是大多橡皮擦仅仅是将画笔改成透明,那么如何才能擦线呢。
我也是第一次玩csdn博客,格式啥的不太了解,大家看看代码就好,其实就是将每次画的点都存入一个集合。
那么就直接放代码了
“`
package com.cavasdemo;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MainActivity extends Activity implements View.OnClickListener {
private ImageView iv;
private Button btn_canvas;
private Button btn_eraser_line;
private Button btn_clear;
private Bitmap baseBitmap;
private Canvas canvas;
private int height;
private int width;
private List<DrawPath> savePath;
private List<DrawPath> deletePath;
private DrawPath drawpath;
private Path mPath;
private float preX, preY;// 之前的XY的位置,用于下面的手势移动
private Paint mBitmapPaint;
private Paint mPaint;
private RectF rf;
private boolean openCanvas = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canvas_view);
initView();
initCanvas();
initListener();
canvas.drawBitmap(baseBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private void initView() {
iv = (ImageView) findViewById(R.id.iv);
btn_canvas = (Button) findViewById(R.id.btn_canvas);
btn_eraser_line = (Button) findViewById(R.id.btn_eraser_line);//橡皮擦线
btn_clear = (Button) findViewById(R.id.btn_clear);
savePath = new ArrayList<>();
deletePath = new ArrayList<DrawPath>();
}
private void initListener() {
btn_canvas.setOnClickListener(this);
btn_eraser_line.setOnClickListener(this);
btn_clear.setOnClickListener(this);
}
private void initCanvas() {
//创建画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setDither(true);
mPaint.setColor(0xFF00FF00);
mPaint.setStyle(Paint.Style.STROKE);// 设置画笔的填充方式为无填充
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(10);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// 获取屏幕的高度与宽度
width = getResources().getDisplayMetrics().widthPixels;
height = getResources().getDisplayMetrics().heightPixels;
baseBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 建立图像缓冲区用来保存图像
//创建一个画布
canvas = new Canvas(baseBitmap);
mPath = new Path();
// 显示旧的画布
canvas.drawBitmap(baseBitmap, 0, 0, mBitmapPaint);
iv.setImageBitmap(baseBitmap);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_canvas://绘图
if (openCanvas) {
btn_canvas.setText("开启画图");
openCanvas = true;
}else {
btn_canvas.setTag("关闭画图");
openCanvas = false;
// 取两层绘制交集。显示上层
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
mPaint.setAntiAlias(true);
//画笔颜色
mPaint.setColor(Color.RED);
//宽度色素
mPaint.setStrokeWidth(5);
iv.setImageBitmap(baseBitmap);
canvas.drawBitmap(baseBitmap, 0, 0, mBitmapPaint);
onTouch();
}
break;
case R.id.btn_eraser_line:
iv.setOnTouchListener(new View.OnTouchListener() {
float mX;
float mY;
@Override
public boolean onTouch(View v, MotionEvent event) {
float moveX = event.getX();
float moveY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mX = moveX;
mY = moveY;
break;
case MotionEvent.ACTION_MOVE:
float dx = Math.abs(moveX - mX);
float dy = Math.abs(moveY - mY);
if (dx > 5 || dy > 5) {// 用户要移动超过5像素才算是画图,免得手滑、手抖现象
mX = moveX;
mY = moveY;
}
//删除滑动区域集合
for (int i = 0; i < savePath.size(); i++) {
RectF rectF = savePath.get(i).rectF;
if (rectF.contains(mX, mY)) {
savePath.remove(i);
}
}
System.out.println(savePath.size());
if (savePath != null && savePath.size() > 0) {
initCanvas();
Iterator<DrawPath> iter = savePath.iterator();
while (iter.hasNext()) {
DrawPath dp = iter.next();
canvas.drawBitmap(baseBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(dp.path, dp.paint);
iv.setImageBitmap(baseBitmap);
}
} else {
initCanvas();
canvas.drawBitmap(baseBitmap, 0, 0, mBitmapPaint);
iv.setImageBitmap(baseBitmap);
}
iv.invalidate();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
break;
case R.id.btn_clear:
//彻底清除画布
removeAllPaint();
break;
}
}
/**
* 清空的主要思想就是初始化画布
* 将保存路径两个List清空
*/
public void removeAllPaint() {
//调用初始化画布函数以清空画布
initCanvas();
iv.invalidate();
savePath.clear();
deletePath.clear();
}
private void touch_start(float x, float y) {
mPath.reset();//清空path
mPath.moveTo(x, y);
preX = x;
preY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - preX);
float dy = Math.abs(y - preY);
if (dx > 5 || dy > 5) {
//源码
mPath.quadTo(preX, preY, (x + preX) / 2, (y + preY) / 2);
canvas.drawPath(mPath, mPaint);
preX = x;
preY = y;
}
}
private void touch_up() {
mPath.lineTo(preX, preY);
mPath.computeBounds(rf, true);
savePath.add(drawpath);
mPath = null;
}
private void onTouch() {
iv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mPath = new Path();
rf = new RectF();
drawpath = new DrawPath();
drawpath.path = mPath;
drawpath.paint = mPaint;
drawpath.rectF = rf;
touch_start(x, y);
iv.invalidate();//刷新
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
iv.invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
iv.invalidate();
break;
}
return true;
}
});
}
}
“`现在适合新手了,慢慢研究吧,一次删掉了很多东西