使用PorterDuffXferMode实现自定义的圆角图片

这里写图片描述
最近研究了下PorterDuffXferMode,也就是图像混合模式。学习了爱哥的自定义View篇的这篇文章:
自定义控件其实很简单1/6。主要学习了关于PorterDuffXfermode的这个部分。具体的关于PorterDuffXfermode的介绍详细,请看爱哥的这篇文章。当看到这个这里写图片描述
就手抖的打开了as想试一下这18中模式,自己也画了源图与目标图之后竟然没有像图中显示的效果展示,麻痹的真是头疼,就百度搜,后来在这篇中找到了原因。 PorterDuffXferMode不正确的真正原因)

真尼玛是久旱逢甘霖的感觉。总结了三个原因:

  1. 必须是两张bitmap才可以使用
  2. 有可能需要关闭硬件加速
  3. 两张bitmap的大小尽量一致

然后写了一个自定义的圆角和圆形图:
还是自定义View的老套路:
(一)属性文件:

<resources>
    <attr name="radious" format="dimension" />
    <attr name="type">
        <enum name="circle" value="0" />
        <enum name="round" value="1" />
    </attr>
    <attr name="src" format="reference" />
    <declare-styleable name="DefineRoundImage">
        <attr name="radious" />
        <attr name="type" />
        <attr name="src" />
    </declare-styleable>
</resources>

(二)onMeasure方法

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            int disWidth = getPaddingLeft() + getPaddingRight() + mBitamap.getWidth();
            if (widthMode == MeasureSpec.AT_MOST) {
                width = Math.min(disWidth, widthSize);
            } else {
                width = disWidth;
            }
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            int disHeight = getPaddingBottom() + getPaddingTop() + mBitamap.getHeight();
            if (heightMode == MeasureSpec.AT_MOST) {
                height = Math.min(disHeight, heightSize);
            } else {
                height = disHeight;
            }
        }
        setMeasuredDimension(width, height);
    }

(三)实现onDraw方法:

 @Override
    protected void onDraw(Canvas canvas) {
        switch (mType) {
            case 0://圆
                //画一个Dis图
                int min = Math.min(width, height);
                Bitmap bitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
                Canvas mCanvas = new Canvas(bitmap);
                mCanvas.drawCircle(min / 2, min / 2, min / 2, mPaint);
                canvas.drawBitmap(bitmap, 0, 0, mPaint);
                mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                mCanvas.drawBitmap(mBitamap, 0, 0, mPaint);
                break;
            case 1:
//                带圆角
                Bitmap roundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
                Canvas roundCanvas = new Canvas(roundBitmap);
                roundCanvas.drawRoundRect(new RectF(0, 0, mBitamap.getWidth(), mBitamap.getHeight()), radious, radious, mPaint);
                canvas.drawBitmap(roundBitmap, 0, 0, mPaint);
                mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                roundCanvas.drawBitmap(mBitamap, 0, 0, mPaint);
                break;
        }
    }

PorterDuffXferMode的Mode为SRC_IN时会显示两张图片重合的SRC也就是源图的部分。
源码
万恶的周一,进步的周一。

猜你喜欢

转载自blog.csdn.net/ljngya/article/details/52840544