• 使用BitmapShader显示圆形头像


    对于一些应用app特别是社交app中,通常需要用户登陆后显示一个圆形的头像作为用户的标识。普通的ImageView是不可以实现这个功能的,那么怎么才能画出一个圆形头像呢?BitmapShader可以帮我们解决这个问题。
    首先来看看BitmapShader的定义,如下:

    Shader used to draw a bitmap as a texture. The bitmap can be repeated or mirrored by setting the tiling mode.

    着色器(shader)用于将bitmap作为纹理绘制到画布上,超出bitmap的部分根据不同的mode作出不同的绘制要求。

    CLAP 渲染器超出原始的位置,将会取边缘的颜色绘制
    MIRROR 以镜像的方式平铺
    REPEAT 横向和纵向重复渲染,类似与平铺



    生成BitmapShader的实例之后,就可以使用paint.setShader(shader)设置paint中将要画的bitmap。所以最后还是通过canvas的drawCircle来完成我们的需求的。

    package com.app.motion.bitmapshadermotion.view;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapShader;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.Shader;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    /**
     * Created by joe.wang on 2016/9/12.
     */
    public class PhotoImageView extends ImageView {
    
        private int mWdith;
        private int mHeight;
        private Paint mPaint;
        private BitmapShader mBitmapShader;
        private Bitmap mBitmap;
        private Rect mDrawableRect;
        private Matrix mShaderMartix;
    
        public PhotoImageView(Context context) {
            this(context, null);
        }
    
        public PhotoImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
    
            mShaderMartix = new Matrix();
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mWdith = w;
            mHeight = h;
            fillDrawableRect();
            setup();
        }
    
        private void setup() {
            if (mBitmap == null) {
                getDrawableBitmap();
            }
        }
    
        /**
         * 获取当前设置的android:src属性中的图片bitmap
         */
        private void getDrawableBitmap() {
            if (getDrawable() == null) {
                return;
            } else {
                Drawable d = getDrawable();
                Bitmap bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);
                d.draw(canvas);
                mBitmap = bitmap;
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (mBitmap == null) {
                super.onDraw(canvas);
            } else {
                getDrawableBitmap();
                mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                updateShaderMatrix();
                mPaint.setShader(mBitmapShader);
                canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRect.width() / 2, mPaint);
            }
        }
    
        /**
         * 获取一个正方形,用于绘制圆形
         */
        private void fillDrawableRect() {
            int avaliableWidth = mWdith - getPaddingLeft() - getPaddingRight();
            int avaliableHeight = mHeight - getPaddingTop() - getPaddingBottom();
            int slideLength = Math.min(avaliableWidth, avaliableHeight);
            int top = getPaddingTop() + (avaliableHeight - slideLength) / 2;
            int left = getPaddingLeft() + (avaliableWidth - slideLength) / 2;
            mDrawableRect = new Rect(left, top, left + slideLength, top + slideLength);
        }
    
        /**
         * 根据不同的比例大小设置bitmap的缩放大小和偏移量
         */
        private void updateShaderMatrix() {
            float scale = 0;
            int dx = 0;
            int dy = 0;
            if (mBitmap.getWidth() * mDrawableRect.height() > mBitmap.getHeight() * mDrawableRect.width()) {
                scale = mDrawableRect.width() * 1.0f / mBitmap.getWidth();
                dy = (int) ((mDrawableRect.height() - mBitmap.getHeight() * scale) * 0.5f);
            } else {
                scale = mDrawableRect.height() * 1.0f / mBitmap.getHeight();
                dx = (int) ((mDrawableRect.width() - mBitmap.getWidth() * scale) * 0.5f);
            }
            mShaderMartix.setScale(scale, scale);
            mShaderMartix.postTranslate(dx + mDrawableRect.left, dy + mDrawableRect.top);
            mBitmapShader.setLocalMatrix(mShaderMartix);
        }
    }
    

    这里写图片描述

  • 相关阅读:
    Java学习笔记之——break 和continue
    Java学习笔记之——循环语句
    Java学习笔记之——switch-case条件结构
    Java学习笔记之——if条件语句和三目运算符
    Java学习笔记之——变量与数据类型、运算符
    supervisor-program配置
    应用节点使用管理节点做代理访问互联网的方法
    运营商-技术问题汇总
    galera cluster,mysql配置wsrep_notify_cmd参数,增加邮件告警
    while循环中出现ssh导致读取文件错误
  • 原文地址:https://www.cnblogs.com/summerpxy/p/13648318.html
Copyright © 2020-2023  润新知