Xfermode实现圆角矩形或者圆角图片

最近一段时间学了很多关于圆角矩形或者圆角图片制作的文章,写的都很好,但是每次一学完都会做,但是过段时间又不记得该怎么写代码了,反思了一下,是自己只是在看,并没有真正的消化,所以还不算自己的东西,于是今天又把大神的代码又看了看,自己总结,自己再写一遍,算是明白了吧,也想写个文章记录一下,方便下次寻找,也可以分享出来。

Xfermode是android画笔Paint可以设置的一种画笔属性,具体就是可以把两张图片进行组合,根据设置的形式,可以组合多种形式,具体大家看图:

这里用的就是SrcIn模式,大致思路就是先绘制一个圆或者圆角矩形,然后再绘制我们的图片,然后根据上面的SrcIn模式,最终就绘制出了圆形图片或者圆角矩形。android里面把先绘制的图片视为Src,后绘制的是Dst。

具体代码如下,里面说的很详细了。

package com.fanxl.roundview;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class RoundView extends View {

	private Bitmap src;
	private Bitmap out;
	private int width;
	private int height;
	private int type;  
	private static final int TYPE_CIRCLE = 0;  
	private static final int TYPE_ROUND = 1; 

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

	public RoundView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RoundView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView();
	}

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

		//自己计算控件的宽高
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);

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

		if (widthMode == MeasureSpec.EXACTLY) {
			width = widthSize;
		} else {
			int imgWidth = src.getWidth() + getPaddingLeft()
					+ getPaddingRight();
			if (widthMode == MeasureSpec.AT_MOST) {
				width = Math.min(widthSize, imgWidth);
			} else {
				width = imgWidth;
			}
		}

		if (heightMode == MeasureSpec.EXACTLY) {
			height = heightSize;
		} else {
			int imgHeight = src.getHeight() + getPaddingTop()
					+ getPaddingBottom();
			if (heightMode == MeasureSpec.AT_MOST) {
				height = Math.min(heightSize, imgHeight);
			} else {
				height = imgHeight;
			}
		}

		//根据要绘制的类型设置最终自定义控件的宽高
		switch (type) {
		case TYPE_CIRCLE:
			int min = Math.min(width, height);
			setMeasuredDimension(min, min);
			break;
		case TYPE_ROUND:
			setMeasuredDimension(width, height);
			break;
		}
	}

	@SuppressLint("NewApi")
	private void initView() {
		// 禁止硬件加速,硬件加速会有一些问题,这里禁用掉
		setLayerType(LAYER_TYPE_SOFTWARE, null);
		src = BitmapFactory.decodeResource(getResources(), R.drawable.dd);
		//设置类型,是圆角图片还是圆角矩形
		type = TYPE_CIRCLE;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		xmodeImage();
		//把画好画的画布放到自定义的画板上面
		canvas.drawBitmap(out, 0, 0, null);
	}

	private void xmodeImage() {
		//根据原始的图片创建一个画布
		out = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		//创建一个画板,在画布的基础上
		Canvas canvas = new Canvas(out);
		//创建一个画笔
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		switch (type) {
		case TYPE_ROUND:
			//开始在有画板的画布上用画笔作画了,这里画了一个圆角矩形
			canvas.drawRoundRect(new RectF(0, 0, width, height),
					60, 60, paint);
			break;
		case TYPE_CIRCLE:
			//画圆,取宽高的最小值作为圆的直径
			int min = Math.min(width, height);
			//开始画圆
			canvas.drawCircle(min/2, min/2, min/2, paint);
			break;
		}
		//设置Xfermode画笔模式为SRC_IN
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		//然后有画了一个图片,最终实现两个图像的叠加
		canvas.drawBitmap(src, 0, 0, paint);
	}

}

最终效果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值