美文网首页
Paint.setXfermode(PorterDuff.Mod

Paint.setXfermode(PorterDuff.Mod

作者: Air_w | 来源:发表于2018-10-24 15:27 被阅读0次

目录:
1、预备:阅读本篇文章,需具备View的绘制基本知识。
2、讲解:PorterDuff.Mode https://developer.android.com/reference/android/graphics/PorterDuff.Mode
3、实战:使用PorterDuff.Mode实现圆形头像。

核心代码:

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));

PorterDuff.Mode

1、SRC

PorterDuff.Mode.SRC

composite_SRC.png
PorterDuff.Mode.SRC_OVER
composite_SRC_OVER.png
PorterDuff.Mode.SRC_IN
composite_SRC_IN.png
PorterDuff.Mode.SRC_OUT
composite_SRC_OUT.png
PorterDuff.Mode.SRC_ATOP
composite_SRC_ATOP.png

2、Destination

PorterDuff.Mode.DST
composite_DST.png
PorterDuff.Mode.DST_OVER
composite_DST_OVER.png
PorterDuff.Mode.DST_IN
composite_DST_IN.png
PorterDuff.Mode.DST_OUT
composite_DST_OUT.png
PorterDuff.Mode.DST_ATOP
composite_DST_ATOP.png

3、Clear

PorterDuff.Mode.CLEAR
composite_CLEAR.png

3、Exclusive or

PorterDuff.Mode.XOR

composite_XOR.png

PorterDuff.Mode,实现圆形头像 (支持Padding、wrap_content属性)

1、核心代码

public class AirXfermodeCircleView extends ImageView {

private static final String TAG = "AirXfermodeCircleView";

private static final int MIN_SIZE_DEFAULT = 100;

private Paint mDrawablePaint;

public AirXfermodeCircleView(Context context) {
    this(context, null);
}

public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
}

public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
}

public AirXfermodeCircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);


    initializePaints();
}

private void initializePaints() {

    mDrawablePaint = new Paint();
    mDrawablePaint.setAntiAlias(true);

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);

    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);


    switch (widthMode) {
        case MeasureSpec.AT_MOST:
            widthSize = dpToPx(MIN_SIZE_DEFAULT);
            break;
    }

    switch (heightMode) {
        case MeasureSpec.AT_MOST:
            heightSize = dpToPx(MIN_SIZE_DEFAULT);
            break;
    }

    int minSize = Math.min(widthSize, heightSize);

    //Update measured dimension.
    setMeasuredDimension(minSize, minSize);
}

@Override
protected void onDraw(Canvas canvas) {
    
    //Canvas circle image.
    drawCircleImage(canvas);

}

/**
 * Draw circle image with paint PorterDuff.
 *
 * @param canvas
 *         canvas.
 */
private void drawCircleImage(Canvas canvas) {
   
    //Save layer with parameter.
    canvas.saveLayerAlpha(getLeft(), getTop(), getRight(), getBottom(), 200);

    //Get drawable source.
    Drawable drawable = getDrawable();
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();

    //Computer circle image radius.
    float radiusX = (getWidth() - getPaddingLeft() - getPaddingRight()) / 2f;
    float radiusY = (getHeight() - getPaddingTop() - getPaddingBottom()) / 2f;
    float radius = Math.min(radiusX, radiusY);

    //Computer
    Rect rectF = new Rect();
    rectF.left = getLeft() + getPaddingLeft();
    rectF.top = getTop() + getPaddingTop();
    rectF.right = getRight() - getPaddingRight();
    rectF.bottom = getBottom() - getPaddingBottom();

    int targetBitmapWidth = rectF.right - rectF.left;
    int targetBitmapHeight = rectF.bottom - rectF.top;

    int diameter = (int) (radius * 2 + 0.5);

    float circleX = getPaddingLeft() + radius;
    float circleY = getPaddingTop() + radius;

    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, targetBitmapWidth, targetBitmapHeight, false);

    /*
    Draw destination bitmap.
     */
    Bitmap bitmapDestination = Bitmap.createBitmap(targetBitmapWidth, targetBitmapHeight, Bitmap.Config.ARGB_8888);
    Canvas canvasDestination = new Canvas(bitmapDestination);
    //Draw circle.
    canvasDestination.drawCircle(circleX, circleY, radius, mDrawablePaint);
    //Draw destination bitmap.
    canvas.drawBitmap(bitmapDestination, 0, 0, mDrawablePaint);

    /*
    Set  paint's porterDuffMode
     */
    mDrawablePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

    /*
    Draw source bitmap.
     */
    canvas.drawBitmap(scaledBitmap, rectF, rectF, mDrawablePaint);

    //Reset mode value.
    mDrawablePaint.setXfermode(null);
    //Restore.
    canvas.restore();
}


private int dpToPx(int dp) {
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5);
}

}

圆形头像效果图

如果,您认为到这里就万事大吉了,那么很遗憾:请看下图

收尾点

所以,在绘制完成后,切记要加上:

Paint.setXfermode(null);

欲知后事如何,请看下篇分解


自此,结束了本篇的学习😊😊😊
如果,您还意犹未尽,请查阅作者更多文集😊😊😊

相关文章

  • Paint.setXfermode(PorterDuff.Mod

    目录:1、预备:阅读本篇文章,需具备View的绘制基本知识。2、讲解:PorterDuff.Mode https:...

  • Paint.setXfermode

    前言 项目需要用到颜色混合模式的开发,查资料看到在绘图时有setXfermode()这个神奇的方法,没想到,在an...

  • Android在onDraw(Canvas canvas)里使用

    2018-07-05 遇到的一点小问题 裁剪 使用Paint.setXfermode(PorterDuff.M...

  • 混合模式

    混合模式的作用就是将两张图片进行无缝结合,类似于PS中的图片融合。可以通过Paint.setXfermode()设...

  • CircleImageView-方式2

    写一个圆形的ImageView 之前有一个通过paint.setXfermode方式去实现的,今天写一个更好地实现...

网友评论

      本文标题:Paint.setXfermode(PorterDuff.Mod

      本文链接:https://www.haomeiwen.com/subject/zsfazftx.html