ImageLoader加载圆形图片

ImageLoader这个图片加载器是我经常使用额一个图片加载器(https://github.com/nostra13/Android-Universal-Image-Loader

这个图片加载器在加载的时候是支持图片加载效果的,原本自带了RoundBitmapDisplayer,圆角图片显示器。

但是项目的需要,我要弄一个圆形的图片,这样有两个思路,

其一,是弄一个CircleImageView 直接改写ImageView 以达到圆形图片的效果

但是这样有个问题,就是在列表加载的时候,这个图片是不能缓存的,每次都是用重新切图

其二,使用ImageLoader的BitmapDisplayer ,这个出来的图片是可以缓存到内存中的,所以在列表中加载比较有优势

 

下面就是实现这种功能代码

首先我们要实现一个最重要的CircleDrawable,就是靠这个实现了圆形的功能

1
  
复制代码
package auggie.library.displayers;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

/**
 * Created With Android Studio
 * User @47
 * Date 2014-07-28
 * Time 0:32
 */
public  class CircleDrawable extends Drawable {
    public static final String TAG = "CircleDrawable";

    protected final Paint paint;

    protected final int margin;
    protected final BitmapShader bitmapShader;
    protected float radius;
    protected Bitmap oBitmap;//原图
    public CircleDrawable(Bitmap bitmap){
        this(bitmap,0);
    }

    public CircleDrawable(Bitmap bitmap, int margin) {
        this.margin = margin;
        this.oBitmap = bitmap;
        bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(bitmapShader);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        computeBitmapShaderSize();
        computeRadius();

    }

    @Override
    public void draw(Canvas canvas) {
        Rect bounds = getBounds();//画一个圆圈
        canvas.drawCircle(bounds.width() / 2F,bounds.height() / 2F,radius,paint);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        paint.setColorFilter(cf);
    }


    /**
     * 计算Bitmap shader 大小
     */
    public void computeBitmapShaderSize(){
        Rect bounds = getBounds();
        if(bounds == null) return;
        //选择缩放比较多的缩放,这样图片就不会有图片拉伸失衡
        Matrix matrix = new Matrix();
        float scaleX = bounds.width() / (float)oBitmap.getWidth();
        float scaleY = bounds.height() / (float)oBitmap.getHeight();
        float scale = scaleX > scaleY ? scaleX : scaleY;
        matrix.postScale(scale,scale);
        bitmapShader.setLocalMatrix(matrix);
    }

    /**
     * 计算半径的大小
     */
    public void computeRadius(){
        Rect bounds = getBounds();
        radius = bounds.width() < bounds.height() ?
                bounds.width() /2F - margin:
                bounds.height() / 2F - margin;
    }
}
复制代码

接着就是CircleBitmapDisplayer 这个外壳

复制代码
package auggie.library.displayers;

import android.graphics.Bitmap;

import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;
import com.nostra13.universalimageloader.core.imageaware.ImageViewAware;

/**
 * Created With Android Studio
 * User @47
 * Date 2014-07-27
 * Time 20:55
 * 显示原型图片的ImageLoader使用的显示器
 *
 */
public class CircleBitmapDisplayer implements BitmapDisplayer {

    protected  final int margin ;

    public CircleBitmapDisplayer() {
        this(0);
    }

    public CircleBitmapDisplayer(int margin) {
        this.margin = margin;
    }

    @Override
    public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
        if (!(imageAware instanceof ImageViewAware)) {
            throw new IllegalArgumentException("ImageAware should wrap ImageView. ImageViewAware is expected.");
        }

        imageAware.setImageDrawable(new CircleDrawable(bitmap, margin));
    }


}
复制代码

这样着在ImageLoader 那里使用就可以了
复制代码
package org.hangox.circleimageview;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;

import auggie.library.displayers.CircleBitmapDisplayer;


public class MainActivity extends ActionBarActivity {
    ImageView iViewCircleImageDisplayer;
    String imageUrl = "http://d.hiphotos.baidu" +
            ".com/image/pic/item/9358d109b3de9c8242a7de176e81800a18d84363.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iViewCircleImageDisplayer = (ImageView) findViewById(R.id.circle_image_displayer);
        ImageLoader.getInstance().displayImage(imageUrl,iViewCircleImageDisplayer,options);
//        BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.test_personal);
//        iViewCircleImageDisplayer.setImageDrawable(new CircleDrawable(bitmapDrawable.getBitmap()));
    }



    DisplayImageOptions options = new DisplayImageOptions.Builder()
            .cacheInMemory(true)
            .cacheOnDisk(true)
            .displayer(new CircleBitmapDisplayer())
            .build();


}
复制代码

效果图:

image

总结:其实我想想做第一种的,结果我就做第二种的,发现第二种可以曲线实现第一种,就是把ImageView里面的Drawable

替换为CircleBitmapDislplayer ,其实这个我是写了的,在分开库的时候不知道为什么代码不见了。。。。。。。。

不过,这个库应该会继续更新,可能会用更多的显示效果

项目地址:https://github.com/L297084910/CircleImageView



  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值