删除android手指画中的功能

时间:2013-05-15 09:00:57

标签: android paint

我在包含背景的图像上做手指画。在图像上绘制一些线条或弧线后,我需要擦除功能,用手指触摸擦除颜色。

我用谷歌搜索了这个,但我没有找到任何适当的解决方案。我正在开发最小的Android版本2.2

这是我到目前为止的代码。

public class DrawPanel extends View {

    private Paint p;
    private ArrayList<Point> points;
    private ArrayList<ArrayList<Point>> strokes;
    private ArrayList<Paint> mVisiblePaints = new ArrayList<Paint>();
    int currentColor;
    boolean isDraw = true;



    public DrawPanel(Context context) {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);
        points = new ArrayList<Point>();
        strokes = new ArrayList<ArrayList<Point>>();
        currentColor = Color.RED;

    }

    @Override
    public void onDraw(Canvas c) {
        super.onDraw(c);
        int i = 0;
        for (ArrayList<Point> obj : strokes) {
            Paint paint = mVisiblePaints.get(i);
            drawStroke( obj, c, paint);
            i++;
        }
        if (p != null)
        drawStroke(points, c, p);



    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            p = createPaint(currentColor, 10);
            invalidate();
        }
        if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
            if (isDraw)
            {
            points.add(new Point((int) event.getX(), (int) event.getY()));
            }
            else
            eraseScreen(new Point((int) event.getX(), (int) event.getY()));
            invalidate();
        }

        if (event.getActionMasked() == MotionEvent.ACTION_UP) 
        {
            this.strokes.add(points);
            points = new ArrayList<Point>();
            mVisiblePaints.add(p);
            invalidate();
        }

        return true;
    }

    private void drawStroke(ArrayList<Point> stroke, Canvas c, Paint paint) {
        if (stroke.size() > 0) {
            Point p0 = (Point) stroke.get(0);
            for (int i = 1; i < stroke.size(); i++) {
                Point p1 = (Point) stroke.get(i);
                c.drawLine(p0.x, p0.y, p1.x, p1.y, paint);
                p0 = p1;
            }
        }
    }

    private Paint createPaint(int color, float width) {
        Paint temp = new Paint();
        temp.setStyle(Paint.Style.STROKE);
        temp.setDither(true);
        temp.setAntiAlias(true);
        temp.setColor(color);
        temp.setStrokeWidth(width);
        temp.setStrokeCap(Cap.ROUND);
        temp.setStrokeJoin(Paint.Join.ROUND);
        return temp;
    }

    /**
     * Sets the current drawing color.
     * 
     * @param color
     */
    public void setColor(int color) {
        currentColor = color;
    }

    public void setIsDraw(boolean isDraw) {
        this.isDraw = isDraw;
    }

    public boolean getIsDraw() {
        return isDraw;
    }

    public void eraseScreen(Point p)
    {
        for(int i=0;i<strokes.size();i++)
        {
            ArrayList<Point> listPoints=strokes.get(i);
            //ArrayList<Point> drawPoints=new ArrayList<Point>();
            if(listPoints.size()>0)
            {
            for(int j=0;j<listPoints.size();j++)
            {
                Point pp=listPoints.get(j);
                float dx = Math.abs(p.x - pp.x);
                float dy = Math.abs(p.y - pp.y);
                if(dx<=5 && dy<=5)
                {
                    listPoints.remove(j);
                }
            }
            strokes.add(i, listPoints);
            }
        }
    }
}

请为此建议解决方案,以实现。

2 个答案:

答案 0 :(得分:2)

正如op要求另类

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

 <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/ll1"
    android:gravity="bottom"
    android:orientation="vertical"
    android:weightSum="1.0" >

    <LinearLayout
        android:id="@+id/view_drawing_pad"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </LinearLayout>
</LinearLayout>
</RelativeLayout>

MainActivity.java

public class FingerPaintActivity extends Activity implements ColorPickerDialog.OnColorChangedListener {    

MyView mv;
AlertDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mv= new MyView(this);
mv.setDrawingCacheEnabled(true);
mv.setBackgroundResource(R.drawable.afor);//set background here
setContentView(mv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(20);

mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
                           0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}

private Paint       mPaint;
private MaskFilter  mEmboss;
private MaskFilter  mBlur;

public void colorChanged(int color) {
mPaint.setColor(color);
}

public class MyView extends View {

private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
private Bitmap  mBitmap;
private Canvas  mCanvas;
private Path    mPath;
private Paint   mBitmapPaint;
Context context;

public MyView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);   
}

@Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);

}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

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

canvas.drawPath(mPath, mPaint);
}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {
//showDialog(); 
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();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
//mPaint.setMaskFilter(null);
}

@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;
}  
}

private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
private static final int ERASE_MENU_ID = Menu.FIRST + 3;
private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
private static final int Save = Menu.FIRST + 5;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);

menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');
menu.add(0, Save, 0, "Save").setShortcut('5', 'z');

return true;
}

@Override
 public boolean onPrepareOptionsMenu(Menu menu) {
 super.onPrepareOptionsMenu(menu);
 return true;
 }

@Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
mPaint.setAlpha(0xFF);

switch (item.getItemId()) {
case COLOR_MENU_ID:
    new ColorPickerDialog(this, this, mPaint.getColor()).show();
    return true;
case EMBOSS_MENU_ID:
    if (mPaint.getMaskFilter() != mEmboss) {
        mPaint.setMaskFilter(mEmboss);
    } else {
        mPaint.setMaskFilter(null);
    }
    return true;
case BLUR_MENU_ID:
    if (mPaint.getMaskFilter() != mBlur) {
        mPaint.setMaskFilter(mBlur);
    } else {
        mPaint.setMaskFilter(null);
    }
    return true;
case ERASE_MENU_ID:
    mPaint.setXfermode(new PorterDuffXfermode(
                                            PorterDuff.Mode.CLEAR));
    return true;
case SRCATOP_MENU_ID:

    mPaint.setXfermode(new PorterDuffXfermode(
                                        PorterDuff.Mode.SRC_ATOP));
    mPaint.setAlpha(0x80);
    return true;
case Save:
    AlertDialog.Builder editalert = new AlertDialog.Builder(FingerPaintActivity.this);
        editalert.setTitle("Please Enter the name with which you want to Save");
        final EditText input = new EditText(FingerPaintActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT,
                LinearLayout.LayoutParams.FILL_PARENT);
        input.setLayoutParams(lp);
        editalert.setView(input);
        editalert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {

            String name= input.getText().toString();
            Bitmap bitmap = mv.getDrawingCache();

         String path = Environment.getExternalStorageDirectory().getAbsolutePath(); 
            File file = new File("/sdcard/"+name+".png");           
            try 
            {
                if(!file.exists())
            {
                file.createNewFile();
            }
                FileOutputStream ostream = new FileOutputStream(file);
                bitmap.compress(CompressFormat.PNG, 10, ostream);

                ostream.close();
                mv.invalidate();                            
            } 
            catch (Exception e) 
            {
                e.printStackTrace();
            }finally
            {

                mv.setDrawingCacheEnabled(false);                           
            }
            }
        });

        editalert.show();       
    return true;    
 }
 return super.onOptionsItemSelected(item);
}
}

的ColorPicker

public class ColorPickerDialog extends Dialog {

public interface OnColorChangedListener {
    void colorChanged(int color);
}

private OnColorChangedListener mListener;
private int mInitialColor;

private static class ColorPickerView extends View {
    private Paint mPaint;
    private Paint mCenterPaint;
    private final int[] mColors;
    private OnColorChangedListener mListener;

    ColorPickerView(Context c, OnColorChangedListener l, int color) {
        super(c);
        mListener = l;
        mColors = new int[] {
            0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
            0xFFFFFF00, 0xFFFF0000
        };
        Shader s = new SweepGradient(0, 0, mColors, null);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setShader(s);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(32);

        mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCenterPaint.setColor(color);
        mCenterPaint.setStrokeWidth(5);
    }

    private boolean mTrackingCenter;
    private boolean mHighlightCenter;

    @Override
    protected void onDraw(Canvas canvas) {
        float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;

        canvas.translate(CENTER_X, CENTER_X);

        canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
        canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);

        if (mTrackingCenter) {
            int c = mCenterPaint.getColor();
            mCenterPaint.setStyle(Paint.Style.STROKE);

            if (mHighlightCenter) {
                mCenterPaint.setAlpha(0xFF);
            } else {
                mCenterPaint.setAlpha(0x80);
            }
            canvas.drawCircle(0, 0,
                              CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
                              mCenterPaint);

            mCenterPaint.setStyle(Paint.Style.FILL);
            mCenterPaint.setColor(c);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
    }

    private static final int CENTER_X = 100;
    private static final int CENTER_Y = 100;
    private static final int CENTER_RADIUS = 32;

    private int floatToByte(float x) {
        int n = java.lang.Math.round(x);
        return n;
    }
    private int pinToByte(int n) {
        if (n < 0) {
            n = 0;
        } else if (n > 255) {
            n = 255;
        }
        return n;
    }

    private int ave(int s, int d, float p) {
        return s + java.lang.Math.round(p * (d - s));
    }

    private int interpColor(int colors[], float unit) {
        if (unit <= 0) {
            return colors[0];
        }
        if (unit >= 1) {
            return colors[colors.length - 1];
        }

        float p = unit * (colors.length - 1);
        int i = (int)p;
        p -= i;

        // now p is just the fractional part [0...1) and i is the index
        int c0 = colors[i];
        int c1 = colors[i+1];
        int a = ave(Color.alpha(c0), Color.alpha(c1), p);
        int r = ave(Color.red(c0), Color.red(c1), p);
        int g = ave(Color.green(c0), Color.green(c1), p);
        int b = ave(Color.blue(c0), Color.blue(c1), p);

        return Color.argb(a, r, g, b);
    }

    private int rotateColor(int color, float rad) {
        float deg = rad * 180 / 3.1415927f;
        int r = Color.red(color);
        int g = Color.green(color);
        int b = Color.blue(color);

        ColorMatrix cm = new ColorMatrix();
        ColorMatrix tmp = new ColorMatrix();

        cm.setRGB2YUV();
        tmp.setRotate(0, deg);
        cm.postConcat(tmp);
        tmp.setYUV2RGB();
        cm.postConcat(tmp);

        final float[] a = cm.getArray();

        int ir = floatToByte(a[0] * r +  a[1] * g +  a[2] * b);
        int ig = floatToByte(a[5] * r +  a[6] * g +  a[7] * b);
        int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);

        return Color.argb(Color.alpha(color), pinToByte(ir),
                          pinToByte(ig), pinToByte(ib));
    }

    private static final float PI = 3.1415926f;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX() - CENTER_X;
        float y = event.getY() - CENTER_Y;
        boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mTrackingCenter = inCenter;
                if (inCenter) {
                    mHighlightCenter = true;
                    invalidate();
                    break;
                }
            case MotionEvent.ACTION_MOVE:
                if (mTrackingCenter) {
                    if (mHighlightCenter != inCenter) {
                        mHighlightCenter = inCenter;
                        invalidate();
                    }
                } else {
                    float angle = (float)java.lang.Math.atan2(y, x);
                    // need to turn angle [-PI ... PI] into unit [0....1]
                    float unit = angle/(2*PI);
                    if (unit < 0) {
                        unit += 1;
                    }
                    mCenterPaint.setColor(interpColor(mColors, unit));
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (mTrackingCenter) {
                    if (inCenter) {
                        mListener.colorChanged(mCenterPaint.getColor());
                    }
                    mTrackingCenter = false;    // so we draw w/o halo
                    invalidate();
                }
                break;
        }
        return true;
    }
}

public ColorPickerDialog(Context context,
                         OnColorChangedListener listener,
                         int initialColor) {
    super(context);

    mListener = listener;
    mInitialColor = initialColor;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    OnColorChangedListener l = new OnColorChangedListener() {
        public void colorChanged(int color) {
            mListener.colorChanged(color);
            dismiss();
        }
    };

    setContentView(new ColorPickerView(getContext(), l, mInitialColor));
    setTitle("Pick a Color");
}
}

您可以从菜单选项中选择删除以进行删除。你会看到部分画面被删除

enter image description here

答案 1 :(得分:0)

我有一个非常类似的问题..只有我的绘图表面,橡皮擦涂料的黑色始终可见..我想要一个像上面的图像但没有得到它的结果..当我保存我的画布时怎么样作为一个png,擦除是正确的..但是在绘图时,你会看到即使在touch_UP之后你制作的所有橡皮擦都是黑色的......请参阅my post