最近發現很多應用都用圓形的Bitmap,心血來潮,lz也寫了一個...技術不佳,寫的很爛,請各位海涵。(源碼在最底下提供下載下傳)
原圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0ETO18VM0MDO4YjN2MTMvw1My8CX0AzMxAjMvw1ckF2bsBXdvwFdl5mLuR2cj5Set1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
效果圖:
這裡簡單的說一下實作原理,lamer可以自然繞過...
實作原理:
1.得到原圖的寬高,計算出圓心,取圖檔的短邊為基準半徑。
2.建立空白Bitmap,大小為基準半徑的正方形。
3.位移原圖,使其中心點和建立的空白圖中心點重合。
4.利用Android的Paint繪制疊加圖,隻繪制重疊部分
5.效果完成。
在這裡我Override了一個ImageView,友善大家直接使用,當然也可以不使用這個ImageVIew,而使用其中靜态的方法,效果是一樣的。
直接上代碼:
/*
* Copyright (C) 2013 'Chaos'.Personal
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.rejuvenation.augment.ui;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 實作圓形的ImageView
* @author Chaos
* @date 2013-4-17
*/
public class CircleImageView extends ImageView{
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CircleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleImageView(Context context) {
super(context);
}
@Override
public void setBackgroundDrawable(Drawable background) {
super.setBackgroundDrawable(getCircleDrawable(getResources(), background));
}
@Override
public void setBackgroundResource(int resid) {
//Don't worry, we don't need to override it,because it will be call
//setBackgroundDrawable(Drawable background)
super.setBackgroundResource(resid);
}
@Override
public void setImageBitmap(Bitmap bm) {
//Don't worry, we don't need to override it,because it will be call
//setImageDrawable(Drawable drawable)
super.setImageBitmap(bm);
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(getCircleDrawable(getResources(), drawable));
}
@Override
public void setImageURI(Uri uri) {
//cheat it, let's change the way to implement
super.setImageURI(uri);
Drawable img = getCircleDrawable(getResources(), getDrawable());
super.setImageDrawable(img);
}
@Override
public void setImageResource(int resId) {
//cheat it, let's change the way to implement
Drawable img = getCircleDrawable(getResources(), resId);
super.setImageDrawable(img);
}
private static final int SPACING_LINE = 2;
private static Paint mCirclePaint = null;
private static Paint mLinePaint = null;
private static Paint getCirclePaint(){
if(mCirclePaint == null){
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
return mCirclePaint;
}
private static Paint getLinePaint(){
if(mLinePaint == null){
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setStyle(Style.STROKE);
//You can use it to change the width of the line
mLinePaint.setStrokeWidth(1);
//You can use it to change the color of the line
mLinePaint.setColor(Color.BLACK);
}
return mLinePaint;
}
/**
* You can call this method to generate the circular bitmap,
* even if you don't use this class
*/
public static Bitmap getCircleBitmap(Bitmap src){
if(src == null){
return null;
}
int width = src.getWidth();
int height = src.getHeight();
int centerX = width / 2;
int centerY = height / 2;
int radius = Math.min(centerX, centerY) / 2;
Bitmap result = Bitmap.createBitmap(radius * 2, radius * 2, Config.ARGB_8888);
Canvas canvas = new Canvas(result);
canvas.drawCircle(radius, radius, radius - SPACING_LINE, getCirclePaint());
getCirclePaint().setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(src, -(centerX - radius), -(centerY - radius), getCirclePaint());
//outer
canvas.drawCircle(radius, radius, radius, getLinePaint());
//inner
canvas.drawCircle(radius, radius, radius - SPACING_LINE, getLinePaint());
//reset
getCirclePaint().setXfermode(null);
//recycle
src.recycle();
return result;
}
public static Bitmap getCircleBitmap(Drawable src){
if(src instanceof BitmapDrawable){
return getCircleBitmap(((BitmapDrawable)src).getBitmap());
}else{
//now, i don't know how to do...
throw new UnsupportedException("Unsupported");
}
}
public static Bitmap getCircleBitmap(Resources res,int id){
return getCircleBitmap(BitmapFactory.decodeResource(res, id));
}
public static Drawable getCircleDrawable(Resources res, Bitmap src){
return new BitmapDrawable(res,getCircleBitmap(src));
}
public static Drawable getCircleDrawable(Resources res, Drawable src){
return new BitmapDrawable(res,getCircleBitmap(src));
}
public static Drawable getCircleDrawable(Resources res, int id) {
return new BitmapDrawable(res, getCircleBitmap(res, id));
}
static class UnsupportedException extends RuntimeException{
private static final long serialVersionUID = 1L;
public UnsupportedException(String str){
super(str);
}
}
}
點選下載下傳源碼