图片加载框架之Glide和Picasso

Glide介绍

Glide是一个加载图片的库,作者是bumptech,它是在泰国举行的google 开发者论坛上google为我们介绍的,这个库被广泛的运用在google的开源项目中。

Glide是一个非常成熟的图片加载库,他可以从多个源加载图片,如:网路,本地,Uri等,更重要的是他内部封装了非常好的缓存机制并且在处理图片的时候能保持一个低的内存消耗。

Picasso介绍(毕加索)

picasso是Square公司开源的一个Android图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能。仅仅只需要一行代码就能完全实现图片的异步加载

1.在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。

2.使用复杂的图片压缩转换来尽可能的减少内存消耗

3.自带内存和硬盘二级缓存功能

二者用法类似,根据gihthub上添加依赖库,添加联网权限



区别:

区别一:with的参数

将Activity/Fragment作为with参数的好处:图片加载和Activity/Fragment的生命周期保持一致,比如Pause状态暂停加载,在resume时候重新加载,建议传参的时候给Activity/Fragment给Glide而不是context

区别二:图片质量

Glide默认的bitmap格式为RGB_565

Picasso默认的bitmap格式为ARGB_8888

区别三:加载Gif图片

Glide的一个明显的优点就是它可以加载gif图片,用Picasso加载的gif图片是不会动的

因为Glide被设计成能和Activity/Fragment的生命周期完美的相结合,因此gif动画将随着Activity/Fragment的生命周期自动的开始和停止。

gif的缓存和一般的图片也是一样的,也是第一次加载的时候调整大小,然后缓存。

注意:gif图片将消耗非常多的内存,因此要慎用。

区别四:缓存策略和加载速度

Picasso的缓存是全尺寸的,而Glide的缓存根据ImageView的尺寸相同

将ImageView调整成不同的大小,不管大小如何,Picasso值缓存一个全尺寸的,Picasso则需要在显示前重新调整大小而导致一下延迟.

而Glide不同,它会为每种大小尺寸缓存一下,加载速度比Picasso更快,磁盘策略比Picasso更好,但需要更大的空间来缓存,Glide比Picasso更有利于减少OOM的发生



基本用法

Glide.with(this).load(url).into(imageView);
Picasso.with(this).load(url).into(imageView);


Glide:修改缓存大小、位置、加载图片质量的实现

自定义一个glideConfigModule.java实体类继承GlideModule

import android.content.Context;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.module.GlideModule;

public class GlideConfigModule implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // 指定位置在packageName/cache/glide_cache,大小为MAX_CACHE_DISK_SIZE的磁盘缓存
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", 10*1024*1024));
        //指定内存缓存大小 Runtime.getRuntime().maxMemory()运行的最大内存值
        builder.setMemoryCache(new LruResourceCache(10*1024*1024));
        //全部的内存缓存用来作为图片缓存
        builder.setBitmapPool(new LruBitmapPool(10*1024*1024));
        //设置图片质量格式,设置和Picasso配置一样
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);/
    }

    @Override
    public void registerComponents(Context context, Glide glide) {

    }
}

在清单文件中配置

<meta-data
    android:name="com.jcf.glidedemo.GlideConfigModule"
    android:value="GlideModule"/>

Glide:不为ImageView类型加载的实现

譬如加载的控件类型不是ImageView,是个自定义的布局。或者加载为Background的形式。可以使用SimpleTarget类型,这里指定他的大小为500*100,加载为背景图片。

.into(new SimpleTarget<GlideDrawable>(500,200) {
    @Override
    public void onResourceReady(GlideDrawable glideDrawable, GlideAnimation<? super GlideDrawable> glideAnimation) {
         tv.setBackground(glideDrawable);
    }
});

Picasso自定义截取图片的实现

import android.graphics.Bitmap;
import com.squareup.picasso.Transformation;
public class CropSquareTransformation implements Transformation {
    @Override
    public Bitmap transform(Bitmap bitmap) {
        int size = Math.min(bitmap.getWidth(), bitmap.getHeight());
        int x = (bitmap.getWidth() - size) / 2;
        int y = (bitmap.getHeight() - size) / 2;
        Bitmap result = Bitmap.createBitmap(bitmap, x, y, size, size);
        if (result != bitmap) {
            bitmap.recycle();
        }
        return result;
    }
    @Override
    public String key() {
        return "square()";
    }
}

使用

Picasso.with(this)
        .load(url)
        .transform(new CropSquareTransformation())
        .into(ivPicasso);


二者在开发中用法

Glide.with(this)
            .load("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1483868451&di=2c4c2a41347e49eca30ee3a2276034c0&src=http://file27.mafengwo.net/M00/B2/12/wKgB6lO0ahWAMhL8AAV1yBFJDJw20.jpeg")
            .crossFade()
            .listener(mRequestListener)//配置监听器
            .animate(android.R.anim.slide_in_left) //配置自带淡出淡入动画
            //.animate(R.anim.scale) //可设置自定义的动画
            .override(100, 100) //为图片重新定义大小
            .placeholder(R.mipmap.ic_launcher)//加载中的图片
            //.fitCenter() //根据布局大小填充图片,必须和centerCrop一起设置设置fitCenter(),不能再调用override()
            //.centerCrop() //图片要填充整个控件,去两边留中间
            .error(R.mipmap.ic_launcher)//加载失败的涂料
            .priority(Priority.HIGH) //优先级
            .into(ivGlide);//加载到控件上
    Picasso.with(this)
           // .load("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1483868451&di=2c4c2a41347e49eca30ee3a2276034c0&src=http://file27.mafengwo.net/M00/B2/12/wKgB6lO0ahWAMhL8AAV1yBFJDJw20.jpeg")
            .load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1483885293073&di=4d6626505c2c3ca8a9e7f580c08884a8&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201510%2F30%2F20151030165654_fyUJW.thumb.700_0.gif")
            .error(R.mipmap.ic_launcher)
            //.fit()   //控件不能设置成wrap_content,也就是必须有大小才行,fit()才让图片的宽高等于控件的宽高,设置fit(),不能再调用resize()
            //.centerCrop()  //图片要填充整个控件,去两边留中间
            .resize(100,100) ////为图片重新定义大小
            .placeholder(R.mipmap.ic_launcher)
            .priority(Picasso.Priority.HIGH)
            .into(ivPicasso);
}
private RequestListener<String, GlideDrawable> mRequestListener = new RequestListener<String, GlideDrawable>() {
    @Override
    public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
        //显示错误信息
        Log.w(TAG, "onException: ", e);
        //打印请求URL
        Log.d(TAG, "onException: " + model);
        //打印请求是否还在进行
        Log.d(TAG, "onException: " + target.getRequest().isRunning());
        return false;
    }

    @Override
    public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
        if (isFromMemoryCache) {
            //如果是从缓存加载,设置动画效果
            ivGlide.setAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale));
        }
        //返回true表示拦截不再传递,false表示事件会传递下去
        return false;

    }
};

Picasso圆形图片的实现

// 自定义Transformation
Transformation transform = new Transformation() {
        @Override
        public Bitmap transform(Bitmap source) {
            int size = Math.min(source.getWidth(), source.getHeight());
            int x = (source.getWidth() - size) / 2;
            int y = (source.getHeight() - size) / 2;
            Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
            if (squaredBitmap != source) {
                source.recycle();
            }
            Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            BitmapShader shader = new BitmapShader(squaredBitmap,
                    BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
            paint.setShader(shader);
            paint.setAntiAlias(true);
            float r = size / 2f;
            canvas.drawCircle(r, r, r, paint);
            squaredBitmap.recycle();
            return bitmap;
        }

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

Picasso
        .with(this)// 指定Context
        .load(URL_IMG2) //指定图片URL
        .transform(transform) // 指定图片转换器
        .into(imageView); // 指定显示图片的ImageView

Picasso圆形图片的实现
class RoundedTransformation implements com.squareup.picasso.Transformation {
    private final int radius;
    private final int margin;  // dp

    // radius is corner radii in dp
    // margin is the board in dp
    public RoundedTransformation(final int radius, final int margin) {
        this.radius = radius;
        this.margin = margin;
    }

    @Override
    public Bitmap transform(final Bitmap source) {
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));

        Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        canvas.drawRoundRect(new RectF(margin, margin, source.getWidth() - margin, source.getHeight() - margin), radius, radius, paint);

        if (source != output) {
            source.recycle();
        }

        return output;
    }

    @Override
    public String key() {
        return "rounded(radius=" + radius + ", margin=" + margin + ")";
    }
}

Picasso
        .with(this)// 指定Context
        .load(URL_IMG2) //指定图片URL
        .transform(new RoundedTransformation(360,0)) // 指定图片转换器
        .into(imageView); // 指定显示图片的ImageView


Glide显示圆形图片的实现

class GlideCircleTransform extends BitmapTransformation {
    public GlideCircleTransform(Context context) {
        super(context);
    }

    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return circleCrop(pool, toTransform);
    }

    private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;

        // TODO this could be acquired from the pool too
        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        float r = size / 2f;
        canvas.drawCircle(r, r, r, paint);
        return result;
    }

    @Override
    public String getId() {
        return getClass().getName();
    }
}

Glide
        .with(this) // 指定Context
        .load(URL_GIF)// 指定图片的URL
        .transform(new GlideCircleTransform(this)) // 指定自定义图片样式
        .into(imageView);//指定显示图片的ImageView

Glide显示圆角图片的实现

class GlideRoundTransform extends BitmapTransformation {

    private  float radius = 0f;

    public GlideRoundTransform(Context context) {
        this(context, 4);
    }

    public GlideRoundTransform(Context context, int dp) {
        super(context);
        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
    }

    @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }

    private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;

        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

    @Override public String getId() {
        return getClass().getName() + Math.round(radius);
    }
}

Glide
        .with(this) // 指定Context
        .load(URL_GIF)// 指定图片的URL
        .transform(new GlideRoundTransform(this,30)) // 指定自定义图片样式
        .into(imageView);//指定显示图片的ImageView


图片加载框架之Glide和Picasso

时间: 2024-10-25 08:54:55

图片加载框架之Glide和Picasso的相关文章

【Android 进阶】图片加载框架之Glide

简介 在泰国举行的谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech.这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app. 特点 (1)使用简单 (2)可配置度高,自适应程度高 (3)支持常见图片格式 : Jpg png gif webp (4)支持多种数据源: 网络.本地.资源.Assets 等 (5)高效缓存策略: 支持Memory和Disk图片缓存,默认Bitmap格式采用RGB_565,内存使用

主流图片加载框架ImageLoader、Glide、Picasso、Fresco性能分析---图片加载速度比较

图片加载这种实现繁琐,可复用性又极强的东西,自然是选择使用图片加载框架来快速实现. 像是Android-Universal-Image-Loader.Glide.Picasso.Fresco之类, 但是这时候的烦恼在于,这么多图片加载框架到底谁最实用? 有说Fresco,因为支持WebP,还是用了NDK来加载图片,减少JavaHeap的使用 有Picasso,简洁高效 有说Glide,Picasso升级,可以加载Gif,在Picasso基础上扩展了很多方法 ImageLoader 使用最广,因为

Android中图片加载框架Glide解析2----从源码的角度理解Glide的执行流程

转载地址:http://blog.csdn.net/guolin_blog/article/details/53939176 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一张图片只需要一行代码就能实现,如下所示: Glide.with(this).load(url).into(i

详谈高大上的图片加载框架Glide

在Android设备上,加载网络图片一直是一个头疼的问题,因为Android设备种类繁多(当然最主要的是配置),处理的稍不周到轻则应用卡顿,严重者就会出现OOM的,导致程序挂掉.现如今网络上有很多图片库,如 Universal-Image-Loader,Picasso,Fresco,Glide等等.相信列举出的这几个库大家都不陌生,这也是目前最火的图片库了.由于个人的喜好原因(主要是别人介绍说Glide库比较NB),所以就开始研究学习Glide. Glide库和Picasso库有极大的相似性,编

详谈高大上的图片加载框架Glide -源码篇

在上篇文章中,我们介绍了Glide图片加载框架的使用,通过之前的学习,我们可能已经能熟练的将Glide图片加载框架运用到我们的项目中,但是如果有人问你它是如何加载,工作原理是怎样的?为什么自定义GlideModule只需要在Manifest文件中加入meta-data即可?等等很多加载流程以及使用的注意事项.当然要想搞明白这些问题,就需要我们对Glide源码有个大致的认识,去剖析源码深处的奥秘. 接下来就让我们一起去进入Glide的源码世界,本篇文章分析的是Glide 3.7.0版本.特别提醒,

android Glide图片加载框架的初探

一.Glide图片加载框架的简介 谷歌2014年开发者论坛会上介绍的图片加载框架,它让我们在处理不管是网路下载的图片还是本地的图片,减轻了很多工作量, 二.开发步骤: 1.添加链接库 compile 'com.github.bumptech.glide:glide:3.7.0' 2.代码编写,主要特性 Glide.with(context) .load(imgUrl) .dontAnimate() .skipMemoryCache(true) .diskCacheStrategy(DiskCac

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53939176 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新. 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一

常用图片加载框架

我们在项目中使用的是Picasso.其实现在的主流图片加载框架除了Picasso还有ImageLoader,Glide,以及Fresco.ImageLoader是比较老的框架了,稳定, 加载速度适中, 缺点在于不支持GIF图片加载, 使用稍微繁琐, 并且缓存机制没有和http的缓存很好的结合, 完全是自己的一套缓存机制.Glide是谷歌的一位工程师开发的,它可以说是Picasso的升级版, 有Picasso的优点, 并且支持GIF图片加载显示, 图片缓存也会自动缩放, 默认使用RGB_565格式

Android中常见的图片加载框架

图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行图片加载. 开源框架的源码还是挺复杂的,但使用较为简单.大部分框架其实都差不多,配置稍微麻烦点,但是使用时一般只需要一行,显示方法一般会提供多个重载方法,支持不同需要.这样会减少很不必要的麻烦.同时,第三方框架的使用较为方便,这大大的减少了工作量.提高了开发效率.本文主要介绍四种常用的图片加载框架,