返回顶部
首页 > 资讯 > 移动开发 >利用Android中BitmapShader制作自带边框的圆形头像
  • 565
分享到

利用Android中BitmapShader制作自带边框的圆形头像

Android 2022-06-06 07:06:24 565人浏览 八月长安
摘要

效果如下: BitmapShader 的简单介绍 关于 Shader是什么,Shader的种类有哪几种以及如何使用不属于本文范畴,对这方面不是很了解的同学,建议先去学习一下

效果如下:

BitmapShader 的简单介绍

关于

Shader
是什么,
Shader
的种类有哪几种以及如何使用不属于本文范畴,对这方面不是很了解的同学,建议先去学习一下
Shader 
的基本使用。

BitmapShader
主要的作用就是 通过Paint对象,对 画布进行指定的
Bitmap
填充,实现一系列效果,可以有以下三种模式进行选择

      1.

CLAMP 
- 拉伸,这里拉伸的是图片的最后一个元素,不断地重复,这个效果,在图片比较小,而所要画的面积比较大的时候会比较明显。

      2.

REPEAT 
- 重复,横向纵向不断地重复,不同于上一模式,这种模式在图片比较小不能满足要求是,会在横向纵向不断重复绘制图形。

      3.

MIRROR 
- 翻转,这种模式和
REPEAT 
是类似的,只不过这里的重复是翻转着重复,和折纸的效果差不多。

而我们将要使用的是

CLAMP 
模式,因为只要我们对图形的大小进行控制,就可以避免图像进行拉伸。

具体实现介绍

为了自定义 图像,边框宽度和颜色,我们首先在 res/values 目录下,新建一个 attrs.xml文件,里面要书写的内容如下所示


<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="MyCustomView">
  <attr name="mborder_color" fORMat="color"></attr>
  <attr name="mborder_width" format="dimension"></attr>
  <attr name="msrc" format="reference"></attr>
 </declare-styleable>
</resources>

当然,在这里还可以添加一些其他的特性。既然定义了我们想要使用的特性,那么我们就要在自定义

View
里面 解析这些属性并且加以利用,解析过程如下所示


 TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
 mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
 mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
 //将获得的 Drawable 转换成 Bitmap
 BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
 mBitmap = bitmapDrawable.getBitmap();
 mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);

值得注意的是

mSrc 
属性的解析,由于获得是
Drawable 
对象,所以我们需要将其转换为
Bitmap 
对象。

下面就利用我们获得的

Bitmap 
对象进行圆形头像的绘制,对
BitmapShader 
Paint 
的初始化如下所示


  mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
  mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  mPaint = new Paint();
  mPaint.setShader(mShader);
  mRadius = (mWidth - mBorderWidth * 2 - 4) / 2;
  mCircleX = (mWidth) / 2;
  mCircleY = (mHeight) / 2;

mSrcBitmap是对获得的图像进行适当的缩小或者放大,以适应我们对图形的要求,而这里的

mWidth 
mHeight 
又是什么呢?实际上就是我们在 定义视图在
 layout_width 
layout_height
中传递进来的值,不过在这里我对他们进行了处理,也就是选取最小值操作,这样的话就可以避免由于宽大于高或者高大于宽而造成图像填充不满指定区域的现象。值得注意的是,自定义视图,需要对
wrap_content 
进行特殊处理,否则系统对该属性的视图不予以显示。至于如何进行处理,可以看看本例的源码,很简单,相信很多人一看就知道或者说早就了然于胸。

还有一点需要强调的是这里的

mRadius 
,也就是将要绘制的圆的半径,为什么要减去边框的宽度 乘 2 呢? 要知道,我们的圆是根据 视图指定的宽度或者高度来画的,如果我们所画 的圆恰好是指定视图的内切圆,那么边框放在哪里呢?它肯定要被画在视图的外面,那样我们就看不到完整的边框了。所以,这么减去的意义在于为边框腾出空间。

经过以上操作,我们就已经将圆形头像绘制出来了,下面来绘制边框,其实非常简单,我只不过是又定义了一个 

Paint 
对象,并且利用它画了一个圆而已,画笔的初始化操作如下所示


  mBorderPaint = new Paint();
  mBorderPaint.setStyle(Paint.Style.STROKE);
  mBorderPaint.setStrokeWidth(mBorderWidth);
  mBorderPaint.setColor(mBorderColor);
  mBorderPaint.setStrokeCap(Paint.Cap.ROUND);

好了,下面就可以在

onDraw()
函数中,进行绘制了,如下所示


 @Override
 protected void onDraw(canvas canvas) {
  super.onDraw(canvas);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
 }

这样,整个效果就算实现完毕了。下面来看看如何使用


 <com.example.hwaphon.patheffecttest.MyView
   Android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginBottom="16dp"
   android:layout_marginRight="8dp"
   app:mborder_color="@android:color/holo_green_light"
   app:mborder_width="4dp"
   app:msrc="@drawable/myview_test"/>

注意,一定要在容器中加上这么一句


xmlns:app=Http://schemas.android.com/apk/res-auto

具体实现的核心代码


package com.example.hwaphon.patheffecttest;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
 private Bitmap mBitmap;
 private Drawable mDrawable;
 private Bitmap mSrcBitmap;
 private BitmapShader mShader;
 private Paint mPaint;
 private int mWidth, mHeight;
 private int mRadius;
 private int mCircleX, mCircleY;
 private int mBorderColor;
 private Paint mBorderPaint;
 private int mBorderWidth;
 public MyView(Context context) {
  this(context, null);
 }
 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
  mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
  mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
  //将获得的 Drawable 转换成 Bitmap
  BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
  mBitmap = bitmapDrawable.getBitmap();
  mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
 }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mWidth = measureWidth(widthMeasureSpec);
  mHeight = measureHeight(heightMeasureSpec);
  int temp = mWidth > mHeight ? mHeight : mWidth;
  mWidth = mHeight = temp;
  initView();
  setMeasuredDimension(mWidth, mHeight);
 }
 private int measureHeight(int heightMeasureSpec) {
  int size = MeasureSpec.getSize(heightMeasureSpec);
  int sizeMode = MeasureSpec.getMode(heightMeasureSpec);
  int result = 0;
  if (sizeMode == MeasureSpec.EXACTLY) {
   result = size;
  } else {
   result = 200;
   if (sizeMode == MeasureSpec.AT_MOST) {
    result = Math.min(result, size);
   }
  }
  return result;
 }
 private int measureWidth(int widthMeasureSpec) {
  int size = MeasureSpec.getSize(widthMeasureSpec);
  int sizeMode = MeasureSpec.getMode(widthMeasureSpec);
  int result = 0;
  if (sizeMode == MeasureSpec.EXACTLY) {
   result = size;
  } else {
   result = 200;
   if (sizeMode == MeasureSpec.AT_MOST) {
    result = Math.min(result, size);
   }
  }
  return result;
 }
 private void initView() {
  mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
  mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  mPaint = new Paint();
  mPaint.setShader(mShader);
  mRadius = (mWidth - mBorderWidth * 2) / 2;
  mCircleX = (mWidth) / 2;
  mCircleY = (mHeight) / 2;
  mBorderPaint = new Paint();
  mBorderPaint.setStyle(Paint.Style.STROKE);
  mBorderPaint.setStrokeWidth(mBorderWidth);
  mBorderPaint.setColor(mBorderColor);
  mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
  mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
 }
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
  canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
 }
}

总结

以上就是Android利用BitmapShader制作自带边框圆形头像的全部内容,希望这篇文章对大家开发Android的时候能有所帮助,如果有疑问大家可以留言交流。

您可能感兴趣的文章:Android一行代码实现圆形头像Android仿QQ圆形头像个性名片Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码Android利用CircleImageView实现圆形头像的方法Android自定义控件仿QQ编辑和选取圆形头像Android使用CircleImageView实现圆形头像的方法Android中使用CircleImageView和Cardview制作圆形头像的方法Android应用中绘制圆形头像的方法解析Android实现本地上传图片并设置为圆形头像Android Studio实现带边框的圆形头像


--结束END--

本文标题: 利用Android中BitmapShader制作自带边框的圆形头像

本文链接: https://lsjlt.com/news/23890.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作