我正在创建一个利用下面的DrawingSurfaceView类的绘图应用程序.在那个类中,我有一个Paint Called橡皮擦,用户可以打开和关闭..当在那个油漆上假设橡皮擦的路径是什么.但它只是画了一条黑线..
当我将画布保存为透明png时,橡皮擦是正确的,但在屏幕上显示黑色..
用于在blob上写“Erik”的EraserPaint手机屏幕截图
从画布中保存了PNG
eraserPaint看起来像这样:
eraserPaint = new Paint(); eraserPaint.setAlpha(0); eraserPaint.setColor(Color.TRANSPARENT); eraserPaint.setStrokeWidth(60); eraserPaint.setStyle(Style.STROKE); eraserPaint.setMaskFilter(null); eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); eraserPaint.setAntiAlias(true);
整个班级
public KNDrawingSurfaceView(Context c,float width,float height,KNSketchBookActivity parent) { super(c); myWidth = width; myHeight = height; mBitmap = Bitmap.createBitmap((int) myWidth,(int) myHeight,Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); _parent = parent; mEmboss = new EmbossMaskFilter(new float[] { 1,1,1 },0.4f,6,3.5f); tile = new Paint(); tileImage = BitmapFactory.decodeResource(getResources(),R.drawable.checkerpattern); shader = new BitmapShader(tileImage,Shader.TileMode.REPEAT,Shader.TileMode.REPEAT); tile.setShader(shader); mPath = new Path(); eraserPaint = new Paint(); eraserPaint.setAlpha(0x00); eraserPaint.setColor(Color.TRANSPARENT); eraserPaint.setStrokeWidth(60); eraserPaint.setStyle(Style.STROKE); //eraserPaint.setMaskFilter(null); eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); eraserPaint.setAntiAlias(true); mBitmapPaint = new Paint(Paint.DITHER_FLAG); mCanvas.drawRect(0,myWidth,myHeight,tile); mCanvas.drawBitmap(mBitmap,mBitmapPaint); mCanvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR); } @Override protected void onSizeChanged(int w,int h,int oldw,int oldh) { super.onSizeChanged(w,h,oldw,oldh); } @Override protected void onDraw(Canvas canvas) { if (!_parent.isDrawerOpen()&&mPaint!=null) { Log.v("onDraw:","curent paths size:" + paths.size()); //mCanvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR); //canvas.drawPath(mPath,mPaint); for (int i=0;i< paths.size();i++) { tempPaint = paints.get(i); eraserPaint.setStrokeWidth(tempPaint.getStrokeWidth()); if(fills.get(i)){ tempPaint.setStyle(Style.FILL_AND_STROKE); eraserPaint.setStyle(Style.FILL_AND_STROKE); }else{ tempPaint.setStyle(Style.STROKE); eraserPaint.setStyle(Style.STROKE); } if(erasers.get(i)){ //tempPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawPath(paths.get(i),eraserPaint); }else{ //tempPaint.setXfermode(null); canvas.drawPath(paths.get(i),tempPaint); } //canvas.drawPath(paths.get(i),tempPaint); } if(_parent.toggleFill.isChecked()){ mPaint.setStyle(Style.FILL_AND_STROKE); eraserPaint.setStyle(Style.FILL_AND_STROKE); }else{ mPaint.setStyle(Style.STROKE); eraserPaint.setStyle(Style.STROKE); } if(_parent.toggleErase.isChecked()){ //mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawPath(mPath,eraserPaint); }else{ //mPaint.setXfermode(null); canvas.drawPath(mPath,mPaint); } //canvas.drawPath(mPath,mPaint); } } public void onClickUndo() { if (paths.size() > 0) { undonePaths.add(paths.remove(paths.size() - 1)); undonePaints.add(paints.remove(paints.size() - 1)); undoneFills.add(fills.remove(fills.size() - 1)); undoneErasers.add(erasers.remove(erasers.size() - 1)); clearCanvasCache(); invalidate(); } else { } _parent.checkButtonStates(); } public void onClickRedo() { if (undonePaths.size() > 0) { paths.add(undonePaths.remove(undonePaths.size() - 1)); paints.add(undonePaints.remove(undonePaints.size() - 1)); fills.add(undoneFills.remove(undoneFills.size() - 1)); erasers.add(undoneErasers.remove(undoneErasers.size() - 1)); clearCanvasCache(); invalidate(); } else { } _parent.checkButtonStates(); } public void onClickClear() { paths.clear(); paints.clear(); fills.clear(); erasers.clear(); undoneFills.clear(); undonePaths.clear(); undonePaints.clear(); undoneErasers.clear(); clearCanvasCache(); invalidate(); _parent.checkButtonStates(); } public void saveDrawing() { FileOutputStream outStream = null; String fileName = "tempTag"; try { outStream = new FileOutputStream("/sdcard/" + fileName + ".png"); mBitmap.compress(Bitmap.CompressFormat.PNG,100,outStream); outStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { } } private float mX,mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x,float y) { undonePaths.clear(); undonePaints.clear(); undoneFills.clear(); 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 if(_parent.toggleErase.isChecked()){ mCanvas.drawPath(mPath,eraserPaint); erasers.add(true); paints.add(eraserPaint); }else{ mCanvas.drawPath(mPath,mPaint); erasers.add(false); paints.add(mPaint); } // kill this so we don't double draw paths.add(mPath); if(_parent.toggleFill.isChecked()){ fills.add(true); }else{ fills.add(false); } if(_parent.toggleErase.isChecked()){ erasers.add(true); }else{ erasers.add(false); } _parent.checkButtonStates(); mPath = new Path(); } @Override public boolean onTouchEvent(MotionEvent event) { if(mPaint==null &&!_parent._showingAlert){ _parent.showNoPaintAlert(); } if (!_parent.isDrawerOpen()&&mPaint!=null) { float x = event.getX(); float y = event.getY(); if (x > myWidth) { x = myWidth; } if (y > myHeight) { y = myHeight; } 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; } else { return true; } } public void clearCanvasCache() { mBitmap = Bitmap.createBitmap((int) myWidth,Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } }
我应该补充一点,我将这个自定义视图添加到具有方格图案作为背景图像的相对布局中.
请请帮助..我需要使用橡皮擦涂料后不显示黑色的预览图像..我需要它来显示背后的方格图案..我知道橡皮擦正在工作,因为那些黑色橡皮擦标记保存为透明.
新笔记
我在玩耍,发现了一些好奇的东西.试验,我试图从绘图切换到画布传递给onDraw方法,并直接到我在构造函数mCanvas中设置的画布,并注意到它没有绘制到我能看到的..所以我添加了一个日志到像这样的onDraw:
protected void onDraw(Canvas canvas) { Log.v("DRAWING SURFACE","canvas:"+canvas+" mCanvas:"+mCanvas);
吐出来的
06-21 11:10:43.994: V/DRAWING SURFACE(4532): canvas:android.view.Surface$CompatibleCanvas@42a8c030 mCanvas:android.graphics.Canvas@431df180
解决方法
我的应用程序遇到了同样的问题.我甚至尝试了“手指画”示例代码,但仍然遇到了同样的问题.我从来没有能够将橡皮擦作为一条路径,但我能够找到一种解决方法.当我擦除时,我绘制一个圆圈(可能是任何形状),而不是在用户放下手指或有“移动”事件时:
case MotionEvent.ACTION_DOWN: mPaint.setStrokeWidth(25); mPaint.setXfermode(new PorterDuffXfermode( PorterDuff.Mode.CLEAR)); mCanvas.drawCircle(x,y,10,mPaint); isErase = true; invalidate(); } touch_start(x,y); invalidate(); break; case MotionEvent.ACTION_MOVE: if(isErase) { mCanvas.drawCircle(x,20,mPaint); } else{ touch_move(x,y); }invalidate(); break;
将它合并到您的代码中需要一些时间,但我保证您花费的时间少于您尝试解决此问题所花费的时间.如果您认为它有用,我可以向您发送更多我的PaintView.