Android(安卓)圆角&圆形图片
16lz
2021-01-26
利用 Xfermode 实现
import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.graphics.Xfermode;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;import java.lang.ref.WeakReference;/** * Created by wangzenghui on 15/8/24. */public class RoundImageView extends ImageView { public static final int TYPE_CIRCLE = 0; public static final int TYPE_ROUND = 1; public static final int BORDER_RADIUS_DEFAULT = 10; private Paint mPaint; private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN); private Bitmap mMaskBitmap; private WeakReference mWeakBitmap; private int mType = TYPE_CIRCLE; private int mBorderRadius = BORDER_RADIUS_DEFAULT; public RoundImageView(Context context) { this(context, null); } public RoundImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setAntiAlias(true); if (attrs != null) { } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mType == TYPE_CIRCLE) { int width = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); setMeasuredDimension(width, width); } } @Override protected void onDraw(Canvas canvas) { Bitmap bitmap = mWeakBitmap == null ? null : mWeakBitmap.get(); if (bitmap == null || bitmap.isRecycled()) { Drawable drawable = getDrawable(); int dWidth = drawable.getIntrinsicWidth(); int dHeight = drawable.getIntrinsicHeight(); if (drawable != null) { bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); float scale = 1.0f; Canvas drawCanvas = new Canvas(bitmap); if (mType == TYPE_ROUND) { scale = Math.max(getWidth() * 1.0f / dWidth, getHeight() * 1.0f / dHeight); } else if (mType == TYPE_CIRCLE) { scale = getWidth() * 1.0f / Math.min(dWidth, dHeight); } drawable.setBounds(0, 0, (int) (scale * dWidth), (int) (scale * dHeight)); drawable.draw(drawCanvas); if (mMaskBitmap == null || mMaskBitmap.isRecycled()) { mMaskBitmap = getBitmap(); } mPaint.reset(); mPaint.setFilterBitmap(false); mPaint.setXfermode(mXfermode); //绘制形状 drawCanvas.drawBitmap(mMaskBitmap, 0, 0, mPaint); mPaint.setXfermode(null); //将准备好的bitmap绘制出来 canvas.drawBitmap(bitmap, 0, 0, null); //bitmap缓存起来,避免每次调用onDraw,分配内存 mWeakBitmap = new WeakReference(bitmap); } } //如果bitmap还存在,则直接绘制即可 if (bitmap != null) { mPaint.setXfermode(null); canvas.drawBitmap(bitmap, 0.0f, 0.0f, mPaint); return; } } public Bitmap getBitmap() { Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLACK); if (mType == TYPE_ROUND) { canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mBorderRadius, mBorderRadius, paint); } else { canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, mPaint); } return bitmap; } @Override public void invalidate() { mWeakBitmap = null; if (mMaskBitmap != null) { mMaskBitmap.recycle(); mMaskBitmap = null; } super.invalidate(); }}
1.PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
显示上层绘制图片
3.PorterDuff.Mode.DST
显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色
Canvas canvas = new Canvas(dst);paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));canvas.drawBitmap(src, 0f, 0f, paint);
更多实现方式
更多相关文章
- Android学习之抽象类AbsListView
- Android(安卓)图片添加水印
- 绘制直角坐标系
- [Android] 零碎知识汇总 - RecyclerView 顶部悬浮
- Android_绘制圆形图片
- Android(安卓)基于surfaceView绘制正弦曲线
- android recycler添加分割线 点击事件等
- View 绘制机制 -- How Android(安卓)Draws Views
- Android屏幕简单 截图