1. 程式人生 > >Android圖片載入框架——Picasso和Glide

Android圖片載入框架——Picasso和Glide

       首先說Picasso,Picasso 是 Square 公司的傑作,名字叫「畢加索,充滿文藝氣息,意為載入圖片就像畫畫一樣,是一門藝術。Picasso 不僅具備載入圖片的強大功能,還是如此的簡潔。

Picasso預設的快取分配大小特點:
  LRU快取佔應用程式可用記憶體的15%
  本地快取佔到硬碟空間的2%但不超過50M並且不小於5M(前提是這種情況只在4.0以上有效果,或者你能像OKHttp那樣提供
  一個本地快取庫來支援全平臺)
  Picasso預設開啟3個執行緒來進行本地與網路之間的訪問
  Picasso載入圖片順序, 記憶體–>本地–>網路

github地址

https://github.com/square/picasso

使用例項:

public class PicassoActivity extends AppCompatActivity {

    private ImageView mLoadImg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loader_img);
        mLoadImg = (ImageView) findViewById(R.id.loadImg);
    }
    //點選事件
    public void loadImage(View view) {
//        basicLoad(ImageUrls.bigImages[4],mLoadImg);

//        loadAndSaveImage(ImageUrls.bigImages[5],mLoadImg);

        tranformationImage(ImageUrls.bigImages[6],mLoadImg);
    }

    //1.picasso的基本用法
    private void basicLoad(String url,ImageView iv){
        Picasso.with(this)    //context
               .load(url)     //圖片載入地址
               .placeholder(R.mipmap.ic_launcher)    //圖片載入中顯示的頁面
               .error(android.R.drawable.ic_menu_delete)   //圖片記載失敗時顯示的頁面
               .noFade()       //設定淡入淡出效果
               .resize(500,400)     //自定義圖片載入的大小,會根據你傳入的尺寸進行取樣
               .centerCrop()    //圖片會被裁剪,但是質量沒有影響,等比例放大
//             .centerInside()   //圖片完整展示,不會被壓縮或擠壓,一般是等比例縮小
//             .fit()      //智慧展示圖片,對於圖片的大小和imageview的尺寸進行了測量,計算出最佳的大小和最佳的質量顯示出來
               .into(iv);    //需要載入圖片的控制元件
    }

    //2.Picasso 載入的圖片的bitmap物件並且儲存到磁碟當中
    private void loadAndSaveImage(String imgUrl,ImageView iv){
        Picasso.with(this)
                .load(imgUrl)
                .rotate(90f)   //簡單的旋轉處理,傳入的資料大於0度小於360度
                .into(target);
    }
    //Target不能寫成匿名內部類形式,垃圾回收器在你獲取不到bitmap的引用時,會把他回收
    private Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            //載入成功後,得到bitmap物件,可以對其進行操作
            mLoadImg.setImageBitmap(bitmap);
            File file = new File(getExternalCacheDir().getAbsolutePath()+File.separator+"picasso.png");
            try {
                FileOutputStream fos = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onBitmapFailed(Drawable errorDrawable) {

        }
        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {

        }
    };

    //3.Picasso可以定製圖片的處理
    private void tranformationImage(String imgPaht,ImageView iv){
        Picasso.with(this)
                .load(imgPaht)
                .transform(new CircleTransfromation())
                .into(iv);
    }
}
public class CircleTransfromation implements Transformation{
    @Override
    public Bitmap transform(Bitmap source) {
        //對於得到的bitmap進行操作
        //獲取比較小的邊作為正方形的邊
        int size = Math.min(source.getWidth(),source.getHeight());
        int x = (source.getWidth()-size)/2;
        int y = (source.getHeight()-size)/2;

        Bitmap squareBitmap = Bitmap.createBitmap(source,x,y,size,size);
        if (squareBitmap!=source){
            //說明已經經過裁剪了
            source.recycle();
        }
        //把正方形點陣圖作為畫布,畫圓形
        Bitmap bm = Bitmap.createBitmap(size,size,source.getConfig());
        Canvas canvas = new Canvas(bm);
        Paint paint = new Paint();
        BitmapShader shader = new BitmapShader(squareBitmap,BitmapShader.TileMode.CLAMP,
                BitmapShader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setAntiAlias(true);

        float radius = size/2f;
        canvas.drawCircle(radius,radius,radius,paint);
        squareBitmap.recycle();
        return bm;
    }

    @Override
    public String key() {
        return "circle";
    }
}

效果:

         Google一位員工完成了Glide,Glide是基於 Picasso的,依然有儲存了Picasso的簡潔風格,但是在此做了大量優化與改進。Glide 預設的 Bitmap 格式是 RGB_565 格式,而Picasso預設的是 ARGB_8888 格式,這個記憶體開銷要小一半。在磁碟快取方面,Picasso只會快取原始尺寸的圖片,而 Glide 快取的是多種規格,也就意味著 Glide會根據你ImageView的大小來快取相應大小的圖片尺寸,比如你ImageView大小是200*200,原圖是 400*400,而使用Glide 就會快取 200*200規格的圖,而Picasso只會快取 400*400 規格的。這個改進就會導致 Glide 比 Picasso 載入的速度要快,畢竟少了每次裁剪,重新渲染的過程。令人興奮的是Glide 支援載入 Gif 動態圖,而Picasso不支援該特性。

使用例項:

public class GlideActivity extends AppCompatActivity {

    private ImageView mLoadImg;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loader_img);
        mLoadImg = (ImageView) findViewById(R.id.loadImg);
    }

    public void loadImage(View view) {
        basicLoad(ImageUrls.newImageUrls[0],mLoadImg);
    }

    //1.glide的基本用法
    private void basicLoad(String imgPath,ImageView iv){
        Glide.with(this)   //使得glide更容易使用,因為能接收context,activity,fragment物件
             .load(imgPath)
//             .asGif()      //判斷載入的url資源是否是gif格式的資源
             .priority(Priority.HIGH)    //設定優先順序
             .placeholder(R.mipmap.ic_launcher)    //載入中顯示的圖片
             .error(android.R.drawable.ic_menu_delete)//載入失敗顯示的圖片
             .centerCrop()
//             .fitCenter()    //縮放影象,整個顯示在控制元件,儘可能的填滿
            .into(iv);
    }

    //2.獲取glide載入bitmap的方法,能夠顯示並存儲圖片
    private void loadAndSaveImage(String url,ImageView iv){

        Glide.with(this)
                .load(url).asBitmap().into(target);
    }

    SimpleTarget target = new SimpleTarget<Bitmap>(300,600) {
        @Override
        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
            mLoadImg.setImageBitmap(resource);

            File file = new File(getExternalCacheDir().getAbsolutePath()+File.separator+"glide.png");
            try {
                FileOutputStream fos = new FileOutputStream(file);
                resource.compress(Bitmap.CompressFormat.PNG,100,fos);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    };
}