Android中圖片圓形設定三種方法介紹

MG_ZXC發表於2018-03-26

Android開發中經常會用到圓形圖片,比如在使用者頭像設定,現在提供三種主要實現方式:

方案一:使用第三方影像框架 Fresco

1、新增依賴

dependencies {
      compile 'com.facebook.fresco:fresco:0.14.1'
}

2、初始化

public class MyApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this);
    }
}

3、修改 manifest

android:name=".MyApplication"

4、新增網路許可權

 <uses-permission android:name="android.permission.INTERNET"/>

5、檔案佈局

需要新增名稱空間

 xmlns:fresco="http://schemas.android.com/apk/res-auto"

引入

<com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/drawee_img"
        fresco:roundAsCircle="true"
        fresco:roundedCornerRadius="20dp"
        android:layout_width="80dp"
        android:layout_height="80dp" />

6、使用

    SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.drawee_img);
        Uri uri = Uri.parse("http://p7.qhimg.com/dr/200_200_/t01b2e3a907f6ecc29d.jpg");
        draweeView.setImageURI(uri);

方案二:自定義View

public class CircleImageView extends ImageView {
    private Paint mPaint; //畫筆

    private int mRadius; //圓形圖片的半徑

    private float mScale; //圖片的縮放比例

    public CircleImageView(Context context) {
        super(context);
    }

    public CircleImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //因為是圓形圖片,所以應該讓寬高保持一致
        int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
        mRadius = size / 2;
        setMeasuredDimension(size, size);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        mPaint = new Paint();
        Bitmap bitmap = drawableToBitmap(getDrawable());

        //初始化BitmapShader,傳入bitmap物件
        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        //計算縮放比例
        mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth());

        Matrix matrix = new Matrix();
        matrix.setScale(mScale, mScale);
        bitmapShader.setLocalMatrix(matrix);


        mPaint.setShader(bitmapShader);

        //畫圓形,指定好中心點座標、半徑、畫筆
        canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
    }

    //寫一個drawble轉BitMap的方法
    private Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }
}

使用:

 <mgzxc.cn.module2.CircleImageView
        android:id="@+id/image1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:scaleType="centerCrop"
        android:src="@drawable/gangtiexia"
        />

方案三:進行圖片剪下

方式一

public static Bitmap createCircleImage(Bitmap source) { 
      int length = source.getWidth() < source.getHeight() ? source.getWidth() : source.getHeight(); 
      Paint paint = new Paint(); 
      paint.setAntiAlias(true); 
      Bitmap target = Bitmap.createBitmap(length, length, Bitmap.Config.ARGB_8888); 
      Canvas canvas = new Canvas(target); 
      canvas.drawCircle(length / 2, length / 2, length / 2, paint); 
      paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
      canvas.drawBitmap(source, 0, 0, paint); 
      return target; 
 } 

方式二:

public static Bitmap createCircleImage(Bitmap source) { 
         int width = source.getWidth();
         int height = source.getHeight();
         float raduis = Math.min(width, height) * 0.5f;
         Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
         //paint.setColor(Color.RED);
         //畫布設定遮罩效果
         paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
         //處理影像資料
         Bitmap bitmap = Bitmap.createBitmap(width, height, source.getConfig());
         Canvas canvas = new Canvas(bitmap);
         //bitmap的顯示由畫筆paint來決定
          canvas.drawCircle(width * 0.5f, height *0.5f, raduis, paint);
         return bitmap;
} 

與Picasso結合使用:

 Picasso.with(mContext).load(Constant.format(headUrl)).transform(new Transformation() {
            @Override
            public Bitmap transform(Bitmap source) {
                source=createCircleImage(source);
                source.recycle();
                return bitmap;
            }

            //Picasso快取bitmap,下次獲取bitmap, 通過key
            //第一次呼叫用key 存入
            //第二次呼叫用key去取
            @Override
            public String key() {

                Log.d(TAG, "key() called");
                return "key";
            }
        }).into(meHeader);

相關文章