PorterDuffXfermode使用CLEAR模式绘制黑线

时间:2013-08-17 05:43:43

标签: android android-imageview android-drawable android-event

我有一个带有背景和前景图像的imageView。当我尝试使用Path和Paint with Clear设置擦除前景时,而不是删除前景路径,其绘制黑色线条。有人能帮帮我吗?

这是我的代码段

    public class ShowBackgrounOnDrawImage extends ImageView {

  private static final float MINP = 0.25f;
  private static final float MAXP = 0.75f;

  private Bitmap mBitmap, blur = null;
  private Canvas mCanvas;
  private Path mPath;
  private Paint mBitmapPaint;
  public boolean imageLoaded = false;
  private Canvas imageCanvas = null;
  Context here;
  Long width = null, height = null;
  private Paint mPaint;

  public BlurOnDrawImage(Context c) {
    super(c);
    initialize();
  }

  public BlurOnDrawImage(Context context, AttributeSet attrs)
  {
    super(context, attrs);
    initialize();
  }

  public BlurOnDrawImage(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs, defStyle);
    initialize();
  }

  private void initialize() {
    mPath = new Path();
    mPaint = new Paint();
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    mPaint.setColor(Color.TRANSPARENT);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeWidth(10f);
    mPaint.setAntiAlias(true);

    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setStrokeWidth(80f);
  }

  public void setBitmap(Bitmap bitmap) {
    mBitmap = bitmap;
    mCanvas = new Canvas(bitmap);
  }

  @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);
    if (imageLoaded) {
      canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
      canvas.drawPath(mPath, mPaint);
      //canvas.drawPath(circlePath, circlePaint);
    } else {
      //imageCanvas = canvas;
    }
  }

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

  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;
    }
    //circlePath.reset();
    //circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
  }

  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
    //circlePath.reset();
    mPath.reset();
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (!imageLoaded) {
      return super.onTouchEvent(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;
  }
}

由于

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。 我在某处看到这是某些设备上硬件加速的问题, 因此,建议在相应的绘制方法之前禁用硬件加速,以解决此问题,因此在您的情况下,这应该是这样的:

    if (imageLoaded) {
      canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
      setLayerType(LAYER_TYPE_SOFTWARE, null);
      canvas.drawPath(mPath, mPaint);
    } else {
      //imageCanvas = canvas;
    }

这适用于我Mode.CLEAR. 但不是像其他类型的其他类型,例如DST_IN。 我找不到解决这个问题的确切方法。

有使用像这个库中的位图着色器的想法 https://github.com/lopspower/CircularImageView
可能这会起作用,但我不测试它