android自定义view-利用Paint 的 Xfermode 把图片撸成各种形状
来源:互联网 发布:停车位软件哪个好 编辑:程序博客网 时间:2024/06/14 21:22
在上一篇文章 Paint 的 Xfermode 的用法 中回顾了下Xfermode的用法,这篇文章我们来实战下,利用它来将图片绘制成各种形状。
先来一张效果图
实现原理:
- 创建一个抽象类继承ImageView重写ondraw()方法
- 将图片以centerCrop方式显示,
- 绘制要显示成的图形
- 设置图像混合模式
public abstract class GeometryImageView extends AppCompatImageView { protected Paint mPaint = new Paint(); public GeometryImageView(Context context) { super(context); } public GeometryImageView(Context context, AttributeSet attrs) { super(context, attrs); } public GeometryImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable != null) { //设置离屏缓冲 int saveLayer = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG); Bitmap bitmap = getDstBitmap(drawable); canvas.drawBitmap(bitmap, 0, 0, mPaint); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); Bitmap maskBitamp = getMaskBitamp(); canvas.drawBitmap(maskBitamp, 0, 0, mPaint); mPaint.setXfermode(null); canvas.restoreToCount(saveLayer); } } /** * 将设置的图片以centerCrop方式显示 * @param drawable * @return */ @NonNull private Bitmap getDstBitmap(Drawable drawable) { Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas _canvas = new Canvas(bitmap); // final int dwidth = drawable.getIntrinsicWidth(); final int dheight = drawable.getIntrinsicHeight(); final int vwidth = getWidth(); final int vheight = getHeight(); Matrix mDrawMatrix = new Matrix(); float scale; float dx = 0, dy = 0; if (dwidth * vheight > vwidth * dheight) { scale = (float) vheight / (float) dheight; dx = (vwidth - dwidth * scale) * 0.5f; } else { scale = (float) vwidth / (float) dwidth; dy = (vheight - dheight * scale) * 0.5f; } mDrawMatrix.setScale(scale, scale); mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy)); _canvas.concat(mDrawMatrix); drawable.draw(_canvas); return bitmap; } /** * 图形,由子类实现,方便扩展 * @return */ public abstract Bitmap getMaskBitamp();}
然后来一个实现:
public class EquilateralPolygonImageView extends GeometryImageView { private int n; public void setN(int n) { this.n = n; } public EquilateralPolygonImageView(Context context) { this(context, null); } public EquilateralPolygonImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public EquilateralPolygonImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.EquilateralPolygonImageView); int aInteger = a.getInteger(R.styleable.EquilateralPolygonImageView_N, 0); setN(aInteger); } @Override public Bitmap getMaskBitamp() { Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); drawPolygon(new RectF(0, 0, getWidth(), getHeight()), canvas, paint, n); return bitmap; } /** * @param rect * @param canvas * @param paintByLevel * @param number */ public void drawPolygon(RectF rect, Canvas canvas, Paint paintByLevel, int number) { if (number < 3) { return; } float r = (rect.right - rect.left) / 2; float mX = (rect.right + rect.left) / 2; float my = (rect.top + rect.bottom) / 2; Path path = new Path(); for (int i = 0; i <= number; i++) { // - 0.5 : Turn 90 ° counterclockwise float alpha = Double.valueOf(((2f / number) * i - 0.5) * Math.PI).floatValue(); float nextX = mX + Double.valueOf(r * Math.cos(alpha)).floatValue(); float nextY = my + Double.valueOf(r * Math.sin(alpha)).floatValue(); if (i == 0) { path.moveTo(nextX, nextY); } else { path.lineTo(nextX, nextY); } } canvas.drawPath(path, paintByLevel); }}
在布局文件中使用:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" tools:context="com.zomll.myapplication.MainActivity"> <com.zomll.geometryimageview.EquilateralPolygonImageView android:layout_width="100dp" android:layout_height="100dp" app:N="3" android:layout_marginTop="10dp" android:src="@mipmap/a" /> <com.zomll.geometryimageview.EquilateralPolygonImageView android:layout_width="100dp" android:layout_height="100dp" app:N="4" android:layout_marginTop="10dp" android:src="@mipmap/a" /> <com.zomll.geometryimageview.EquilateralPolygonImageView android:layout_width="100dp" android:layout_height="100dp" app:N="5" android:layout_marginTop="10dp" android:src="@mipmap/a" /> <com.zomll.geometryimageview.EquilateralPolygonImageView android:layout_width="100dp" android:layout_height="100dp" app:N="6" android:layout_marginTop="10dp" android:src="@mipmap/a" /></LinearLayout>
全部的代码在:https://github.com/zomll/EquilateralPolygonImageView
阅读全文
0 0
- android自定义view-利用Paint 的 Xfermode 把图片撸成各种形状
- Android自定义View——Paint之Xfermode
- 使用Xfermode实现图片各种形状的抠图
- Android中Paint的setXfermode(Xfermode xfermode)方法讲解
- 自定义View各种形状画法
- android paint Xfermode
- Android自定义View,paint+canvas的使用
- Paint:xfermode的使用
- paint,canvas绘画出来的各种形状
- paint,canvas绘画出来的各种形状
- 详解Paint的setXfermode(Xfermode xfermode)
- 详解Paint的setXfermode(Xfermode xfermode)
- 详解Paint的setXfermode(Xfermode xfermode)
- Android Paint Xfermode 详解(未完)
- 自定义View—使用Xfermode实现圆角图片
- Android 2D Xfermode 理解实现特定形状的头像
- Paint 的 Xfermode 的用法
- 安卓 Paint 的 Xfermode
- HttpServletRequest
- HDU 5875 Function
- 虚拟化技术详解
- hdu 4507 数位DP(求和类型)
- html5 新元素和Canvas
- android自定义view-利用Paint 的 Xfermode 把图片撸成各种形状
- 访问WEB-INF目录中的JSP文件
- hdu1285 确定比赛名次【拓扑排序】
- 机器学习教程之2-k近邻模型的sklearn实现
- OGNL基础
- CentOS 7常用工具安装
- nginx 多层代理 参数丢失
- Cows POJ
- android LayoutInflater