天天看點

【原創】繪制圓形的Bitmap

最近發現很多應用都用圓形的Bitmap,心血來潮,lz也寫了一個...技術不佳,寫的很爛,請各位海涵。(源碼在最底下提供下載下傳)

原圖:

【原創】繪制圓形的Bitmap

效果圖:

【原創】繪制圓形的Bitmap

這裡簡單的說一下實作原理,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);
        }
    }
}
           

點選下載下傳源碼