private Bitmap creataBitmap(Bitmap bitmap) {//用指定的一个Bitmap来构建一个画布Bitmap target = Bitmap.createBitmap(1000,1000, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(target);final Paint paint = new Paint();paint.setColor(Color.GREEN);paint.setAntiAlias(true);//在刚才的画布上绘制一个圆形区域canvas.drawCircle(500,500,500,paint);//设置Xfermode,使用SRC_IN模式,这样可以取到第二张图片重叠后的区域paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//在画布上绘制第二个需要显示的bitmapcanvas.drawBitmap(bitmap,0,0,paint);return target;}上面代码中看出在指定的画布上绘制了两层图像,一个是半径为500像素的圆形,一个是将目标Bitmap绘制在上面。之间还调用了paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));作用是这两个绘制的效果图叠加后,取得第二个图的交集图。所以,我们先绘制一个圆形,然后绘制Bitmap,交集为圆形,取出的就是圆形区域的Bitmap了。
可以根据不同的Mode,控制显示的效果图。
开始应用
1.自定义属性在attrs.xml中
<?xml version="1.0" encoding="utf-8"?><resources><attr name="borderRadius" format="dimension" /><attr name="type"><enum name="circle" value="0"/><enum name="round" value="1"/></attr><attr name="src" format="reference"/><declare-styleable name="RoundImageView"><attr name="borderRadius"/><attr name="type"/><attr name="src"/></declare-styleable></resources>2.自定义View
public class RoundImageView extends View {private int type;private static final int TYPE_CIRCLE = 0;private static final int TYPE_ROUND = 1;//图片private Bitmap mSrc;//圆角大小private int mRadius;//高度private int mWidth;//宽度private int mHeight;public RoundImageView(Context context, AttributeSet attrs) {super(context, attrs);//获取自定义的属性TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.RoundImageView);//获取自定以属性的数目int count = a.getIndexCount();for (int i=0 ; i<count ; i++){int attr = a.getIndex(i);switch (attr){case R.styleable.RoundImageView_borderRadius:int defValue = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10f,getResources().getDisplayMetrics());mRadius = a.getDimensionPixelSize(attr, defValue);break;case R.styleable.RoundImageView_type:type = a.getInt(attr,0);break;case R.styleable.RoundImageView_src:mSrc = BitmapFactory.decodeResource(getResources(),a.getResourceId(attr,0));break;}}a.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//设置宽度int specMode = MeasureSpec.getMode(widthMeasureSpec);int specSize = MeasureSpec.getSize(widthMeasureSpec);if (specMode == MeasureSpec.EXACTLY){mWidth = specSize;}else {int desireByImg = getPaddingLeft() + getPaddingRight() + mSrc.getWidth();if (specMode == MeasureSpec.AT_MOST)// wrap_content{mWidth = Math.min(desireByImg, specSize);} elsemWidth = desireByImg;}//设置高度specMode = MeasureSpec.getMode(heightMeasureSpec);specSize = MeasureSpec.getSize(heightMeasureSpec);if (specMode == MeasureSpec.EXACTLY){mHeight = specSize;}else {int desire = getPaddingTop() + getPaddingBottom() + mSrc.getHeight();if (specMode == MeasureSpec.AT_MOST)// wrap_content{mHeight = Math.min(desire, specSize);} elsemHeight = desire;}setMeasuredDimension(mWidth,mHeight);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);switch (type){case TYPE_CIRCLE:int min = Math.min(mWidth,mHeight);//从当前存在的Bitmap,按一定的比例创建一个新的Bitmap。mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);break;case TYPE_ROUND:mSrc = Bitmap.createScaledBitmap(mSrc, mWidth, mHeight, false);canvas.drawBitmap(createRoundConerImage(mSrc), 0, 0, null);break;}}/** * 绘制圆角 * @param source * @return */private Bitmap createRoundConerImage(Bitmap source) {final Paint paint = new Paint();paint.setAntiAlias(true);Bitmap target = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(target);RectF rect = new RectF(0, 0, mWidth, mHeight);canvas.drawRoundRect(rect, mRadius, mRadius, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(source, 0, 0, paint);return target;}/** * 绘制圆形 * @param source * @param min * @return */private Bitmap createCircleImage(Bitmap source, int min) {final Paint paint = new Paint();paint.setAntiAlias(true);Bitmap target = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(target);canvas.drawCircle(min/2,min/2,min/2,paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(source, 0, 0, paint);return target;}}3.布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:roundview="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" tools:context="mo.yumf.com.myviews.MainActivity"><mo.yumf.com.myviews.RoundImageViewandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="20dp"roundview:borderRadius="10dp"roundview:src="@drawable/ac_default_icon"roundview:type="round"/><mo.yumf.com.myviews.RoundImageViewandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="20dp"roundview:src="@drawable/ac_default_icon"roundview:type="circle"/></LinearLayout>上面的自定义View中,存在一个局限,那就是只能在布局中设置要加载的图片资源,不能在代码中设置图片。下面我们使用同样的方式,选择自定义ImageView来实现。
public class RoundImageView extends ImageView {private int type;private static final int TYPE_CIRCLE = 0;private static final int TYPE_ROUND = 1;//图片private Bitmap mSrc;//圆角大小private int mRadius;public RoundImageView(Context context, AttributeSet attrs) {super(context, attrs);//获取自定义的属性TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.RoundImageView);//获取自定以属性的数目int count = a.getIndexCount();for (int i=0 ; i<count ; i++){int attr = a.getIndex(i);switch (attr){case R.styleable.RoundImageView_borderRadius:int defValue = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10f,getResources().getDisplayMetrics());mRadius = a.getDimensionPixelSize(attr, defValue);break;case R.styleable.RoundImageView_type:type = a.getInt(attr,0);break;}}a.recycle();}@Overrideprotected void onDraw(Canvas canvas) {if (getDrawable() != null){Bitmap bitmap = getBitmap(getDrawable());if (bitmap != null){switch (type){case TYPE_CIRCLE://获取ImageView中的宽高,取最小值int min = Math.min(getMeasuredWidth(),getMeasuredHeight());//从当前存在的Bitmap,按一定的比例创建一个新的Bitmap。mSrc = Bitmap.createScaledBitmap(bitmap, min, min, false);canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);break;case TYPE_ROUND:mSrc = Bitmap.createScaledBitmap(bitmap, getMeasuredWidth(), getMeasuredHeight(), false);canvas.drawBitmap(createRoundConerImage(mSrc), 0, 0, null);break;}}}else {super.onDraw(canvas);}}private Bitmap getBitmap(Drawable drawable) {if (drawable instanceof BitmapDrawable){return ((BitmapDrawable)drawable).getBitmap();}else if (drawable instanceof ColorDrawable){Rect rect = drawable.getBounds();int width = rect.right - rect.left;int height = rect.bottom - rect.top;int color = ((ColorDrawable)drawable).getColor();Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);canvas.drawARGB(Color.alpha(color),Color.red(color), Color.green(color), Color.blue(color));return bitmap;}else {return null;}}/** * 绘制圆角 * @param source * @return */private Bitmap createRoundConerImage(Bitmap source) {final Paint paint = new Paint();paint.setAntiAlias(true);Bitmap target = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(target);RectF rect = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());canvas.drawRoundRect(rect, mRadius, mRadius, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(source, 0, 0, paint);return target;}/** * 绘制圆形 * @param source * @param min * @return */private Bitmap createCircleImage(Bitmap source, int min) {final Paint paint = new Paint();paint.setAntiAlias(true);Bitmap target = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(target);canvas.drawCircle(min/2,min/2,min/2,paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas.drawBitmap(source, 0, 0, paint);return target;}}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。