精华内容
下载资源
问答
  • body{ ...//设置背景图片大小屏幕一样大 background-size:100%; //设置背景图像是否固定,不随着页面的其余部分滚动。 background-attachment: fixed; //设置背景图片不平铺 background-repeat...
     body{
     	//图片
    	background-image: url("../theme/bdhbzf/images/unauthorize.png");
    	//使背景图像完全覆盖屏幕,背景图像的某些部分也许无法显示在背景定位区域中。
     	background-size:cover;
     	//设置背景图像是否固定,不随着页面的其余部分滚动。
    	background-attachment: fixed;
     	//设置背景图片不平铺
    	background-repeat:no-repeat;
     }
    
    展开全文
  • 在前面四篇文章的当中,我们已经学习了Glide的基本用法、Glide的工作原理执行流程、Glide的缓存机制、以及Glide的回调机制等内容。如果你能将前面的四篇文章都掌握好了,那么恭喜你,现在你已经是一名Glide好手了...

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/71524668

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新。

    大家好,又到了学习Glide的时间了。前段时间由于项目开发紧张,再加上后来又生病了,所以停更了一个月,不过现在终于又可以恢复正常更新了。今天是这个系列的第五篇文章,在前面四篇文章的当中,我们已经学习了Glide的基本用法、Glide的工作原理和执行流程、Glide的缓存机制、以及Glide的回调机制等内容。如果你能将前面的四篇文章都掌握好了,那么恭喜你,现在你已经是一名Glide好手了。

    如果你还没有阅读过前面四篇文章的话,那么可以点击后面的链接,依次向前阅读 Android图片加载框架最全解析(四),玩转Glide的回调与监听

    不过Glide的这个框架的功能实在是太强大了,它所能做的事情远远不止于目前我们所学的这些。因此,今天我们就再来学习一个新的功能模块,并且是一个非常重要的模块——Glide的图片变化功能。

    一个问题

    在正式开始学习Glide的图片变化功能之前,我们先来看一个问题,这个问题可能有不少人都在使用Glide的时候都遇到过,正好在本篇内容的主题之下我们顺带着将这个问题给解决了。

    首先我们尝试使用Glide来加载一张图片,图片URL地址是:

    https://www.baidu.com/img/bd_logo1.png

    这是百度首页logo的一张图片,图片尺寸是540*258像素。

    接下来我们编写一个非常简单的布局文件,如下所示:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Load Image"
            android:onClick="loadImage"
            />
    
        <ImageView
            android:id="@+id/image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    </LinearLayout>

    布局文件中只有一个按钮和一个用于显示图片的ImageView。注意,ImageView的宽和高这里设置的都是wrap_content。

    然后编写如下的代码来加载图片:

    public class MainActivity extends AppCompatActivity {
    
        ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = (ImageView) findViewById(R.id.image_view);
        }
    
        public void loadImage(View view) {
            String url = "https://www.baidu.com/img/bd_logo1.png";
            Glide.with(this)
                 .load(url)
                 .into(imageView);
        }
    }

    这些简单的代码对于现在的你而言应该都是小儿科了,相信我也不用再做什么解释。现在运行一下程序并点击加载图片按钮,效果如下图所示。

    图片是正常加载出来了,不过大家有没有发现一个问题。百度这张logo图片的尺寸只有540*258像素,但是我的手机的分辨率却是1080*1920像素,而我们将ImageView的宽高设置的都是wrap_content,那么图片的宽度应该只有手机屏幕宽度的一半而已,但是这里却充满了全屏,这是为什么呢?

    如果你之前也被这个问题困扰过,那么恭喜,本篇文章正是你所需要的。之所以会出现这个现象,就是因为Glide的图片变换功能所导致的。那么接下来我们会先分析如何解决这个问题,然后再深入学习Glide图片变化的更多功能。

    稍微对Android有点了解的人应该都知道ImageView有scaleType这个属性,但是可能大多数人却不知道,如果在没有指定scaleType属性的情况下,ImageView默认的scaleType是什么?

    这个问题如果直接问我,我也答不上来。不过动手才是检验真理的唯一标准,想知道答案,自己动手试一下就知道了。

    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
    
        ImageView imageView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = (ImageView) findViewById(R.id.image_view);
            Log.d(TAG, "imageView scaleType is " + imageView.getScaleType());
        }
    
        ...
    }

    可以看到,我们在onCreate()方法中打印了ImageView默认的scaleType,然后重新运行一下程序,结果如下图所示:

    由此我们可以得知,在没有明确指定的情况下,ImageView默认的scaleType是FIT_CENTER。

    有了这个前提条件,我们就可以继续去分析Glide的源码了。当然,本文中的源码还是建在第二篇源码分析的基础之上,还没有看过这篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

    回顾一下第二篇文章中我们分析过的into()方法,它是在GenericRequestBuilder类当中的,代码如下所示:

    public Target<TranscodeType> into(ImageView view) {
        Util.assertMainThread();
        if (view == null) {
            throw new IllegalArgumentException("You must pass in a non null View");
        }
        if (!isTransformationSet && view.getScaleType() != null) {
            switch (view.getScaleType()) {
                case CENTER_CROP:
                    applyCenterCrop();
                    break;
                case FIT_CENTER:
                case FIT_START:
                case FIT_END:
                    applyFitCenter();
                    break;
                //$CASES-OMITTED$
                default:
                    // Do nothing.
            }
        }
        return into(glide.buildImageViewTarget(view, transcodeClass));
    }

    还记得我们当初分析这段代码的时候,直接跳过前面的所有代码,直奔最后一行。因为那个时候我们的主要任务是分析Glide的主线执行流程,而不去仔细阅读它的细节,但是现在我们是时候应该阅读一下细节了。

    可以看到,这里在第7行会进行一个switch判断,如果ImageView的scaleType是CENTER_CROP,则会去调用applyCenterCrop()方法,如果scaleType是FIT_CENTER、FIT_START或FIT_END,则会去调用applyFitCenter()方法。这里的applyCenterCrop()和applyFitCenter()方法其实就是向Glide的加载流程中添加了一个图片变换操作,具体的源码我们就不跟进去看了。

    那么现在我们就基本清楚了,由于ImageView默认的scaleType是FIT_CENTER,因此会自动添加一个FitCenter的图片变换,而在这个图片变换过程中做了某些操作,导致图片充满了全屏。

    那么我们该如何解决这个问题呢?最直白的一种办法就是看着源码来改。当ImageView的scaleType是CENTER_CROP、FIT_CENTER、FIT_START或FIT_END时不是会自动添加一个图片变换操作吗?那我们把scaleType改成其他值不就可以了。ImageView的scaleType可选值还有CENTER、CENTER_INSIDE、FIT_XY等。这当然是一种解决方案,不过只能说是一种比较笨的解决方案,因为我们为了解决这个问题而去改动了ImageView原有的scaleType,那如果你真的需要ImageView的scaleType为CENTER_CROP或FIT_CENTER时可能就傻眼了。

    上面只是我们通过分析源码得到的一种解决方案,并不推荐大家使用。实际上,Glide给我们提供了专门的API来添加和取消图片变换,想要解决这个问题只需要使用如下代码即可:

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

    可以看到,这里调用了一个dontTransform()方法,表示让Glide在加载图片的过程中不进行图片变换,这样刚才调用的applyCenterCrop()、applyFitCenter()就统统无效了。

    现在我们重新运行一下代码,效果如下图所示:

    这样图片就只会占据半个屏幕的宽度了,说明我们的代码奏效了。

    但是使用dontTransform()方法存在着一个问题,就是调用这个方法之后,所有的图片变换操作就全部失效了,那如果我有一些图片变换操作是必须要执行的该怎么办呢?不用担心,总归是有办法的,这种情况下我们只需要借助override()方法强制将图片尺寸指定成原始大小就可以了,代码如下所示:

    Glide.with(this)
         .load(url)
         .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
         .into(imageView);

    通过override()方法将图片的宽和高都指定成Target.SIZE_ORIGINAL,问题同样被解决了。程序的最终运行结果和上图是完全一样的,我就不再重新截图了。

    由此我们可以看出,之所以会出现这个问题,和Glide的图片变换功能是撇不开关系的。那么也是通过这个问题,我们对Glide的图片变换有了一个最基本的认识。接下来,就让我们正式开始进入本篇文章的正题吧。

    图片变换的基本用法

    顾名思义,图片变换的意思就是说,Glide从加载了原始图片到最终展示给用户之前,又进行了一些变换处理,从而能够实现一些更加丰富的图片效果,如图片圆角化、圆形化、模糊化等等。

    添加图片变换的用法非常简单,我们只需要调用transform()方法,并将想要执行的图片变换操作作为参数传入transform()方法即可,如下所示:

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

    至于具体要进行什么样的图片变换操作,这个通常都是需要我们自己来写的。不过Glide已经内置了两种图片变换操作,我们可以直接拿来使用,一个是CenterCrop,一个是FitCenter。

    但这两种内置的图片变换操作其实都不需要使用transform()方法,Glide为了方便我们使用直接提供了现成的API:

    Glide.with(this)
         .load(url)
         .centerCrop()
         .into(imageView);
    
    Glide.with(this)
         .load(url)
         .fitCenter()
         .into(imageView);

    当然,centerCrop()和fitCenter()方法其实也只是对transform()方法进行了一层封装而已,它们背后的源码仍然还是借助transform()方法来实现的,如下所示:

    public class DrawableRequestBuilder<ModelType>
            extends GenericRequestBuilder<ModelType, ImageVideoWrapper, GifBitmapWrapper, GlideDrawable>
            implements BitmapOptions, DrawableOptions {
        ...
    
        /**
         * Transform {@link GlideDrawable}s using {@link com.bumptech.glide.load.resource.bitmap.CenterCrop}.
         *
         * @see #fitCenter()
         * @see #transform(BitmapTransformation...)
         * @see #bitmapTransform(Transformation[])
         * @see #transform(Transformation[])
         *
         * @return This request builder.
         */
        @SuppressWarnings("unchecked")
        public DrawableRequestBuilder<ModelType> centerCrop() {
            return transform(glide.getDrawableCenterCrop());
        }
    
        /**
         * Transform {@link GlideDrawable}s using {@link com.bumptech.glide.load.resource.bitmap.FitCenter}.
         *
         * @see #centerCrop()
         * @see #transform(BitmapTransformation...)
         * @see #bitmapTransform(Transformation[])
         * @see #transform(Transformation[])
         *
         * @return This request builder.
         */
        @SuppressWarnings("unchecked")
        public DrawableRequestBuilder<ModelType> fitCenter() {
            return transform(glide.getDrawableFitCenter());
        }
    
        ...
    }

    那么这两种内置的图片变换操作到底能实现什么样的效果呢?FitCenter的效果其实刚才我们已经见识过了,就是会将图片按照原始的长宽比充满全屏。那么CenterCrop又是什么样的效果呢?我们来动手试一下就知道了。

    为了让效果更加明显,这里我就不使用百度首页的Logo图了,而是换成必应首页的一张美图。在不应用任何图片变换的情况下,使用Glide加载必应这张图片效果如下所示。

    现在我们添加一个CenterCrop的图片变换操作,代码如下:

    String url = "http://cn.bing.com/az/hprichbg/rb/AvalancheCreek_ROW11173354624_1920x1080.jpg";
    Glide.with(this)
         .load(url)
         .centerCrop()
         .into(imageView);

    重新运行一下程序并点击加载图片按钮,效果如下图所示。

    可以看到,现在展示的图片是对原图的中心区域进行裁剪后得到的图片。

    另外,centerCrop()方法还可以配合override()方法来实现更加丰富的效果,比如指定图片裁剪的比例:

    String url = "http://cn.bing.com/az/hprichbg/rb/AvalancheCreek_ROW11173354624_1920x1080.jpg";
    Glide.with(this)
         .load(url)
         .override(500, 500)
         .centerCrop()
         .into(imageView);

    可以看到,这里我们将图片的尺寸设定为500*500像素,那么裁剪的比例也就变成1:1了,现在重新运行一下程序,效果如下图所示。

    这样我们就把Glide内置的图片变换接口的用法都掌握了。不过不得不说,Glide内置的图片变换接口功能十分单一且有限,完全没有办法满足我们平时的开发需求。因此,掌握自定义图片变换功能就显得尤为重要了。

    不过,在正式开始学习自定义图片变换功能之前,我们先来探究一下CenterCrop这种图片变换的源码,理解了它的源码我们再来进行自定义图片变换就能更加得心应手了。

    源码分析

    那么就话不多说,我们直接打开CenterCrop类来看一下它的源码吧,如下所示:

    public class CenterCrop extends BitmapTransformation {
    
        public CenterCrop(Context context) {
            super(context);
        }
    
        public CenterCrop(BitmapPool bitmapPool) {
            super(bitmapPool);
        }
    
        // Bitmap doesn't implement equals, so == and .equals are equivalent here.
        @SuppressWarnings("PMD.CompareObjectsWithEquals")
        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            final Bitmap toReuse = pool.get(outWidth, outHeight, toTransform.getConfig() != null
                    ? toTransform.getConfig() : Bitmap.Config.ARGB_8888);
            Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight);
            if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) {
                toReuse.recycle();
            }
            return transformed;
        }
    
        @Override
        public String getId() {
            return "CenterCrop.com.bumptech.glide.load.resource.bitmap";
        }
    }

    这段代码并不长,但是我还是要划下重点,这样大家看起来的时候会更加轻松。

    首先,CenterCrop是继承自BitmapTransformation的,这个是重中之重,因为整个图片变换功能都是建立在这个继承结构基础上的。

    接下来CenterCrop中最重要的就是transform()方法,其他的方法我们可以暂时忽略。transform()方法中有四个参数,每一个都很重要,我们来一一解读下。第一个参数pool,这个是Glide中的一个Bitmap缓存池,用于对Bitmap对象进行重用,否则每次图片变换都重新创建Bitmap对象将会非常消耗内存。第二个参数toTransform,这个是原始图片的Bitmap对象,我们就是要对它来进行图片变换。第三和第四个参数比较简单,分别代表图片变换后的宽度和高度,其实也就是override()方法中传入的宽和高的值了。

    下面我们来看一下transform()方法的细节,首先第一行就从Bitmap缓存池中尝试获取一个可重用的Bitmap对象,然后把这个对象连同toTransform、outWidth、outHeight参数一起传入到了TransformationUtils.centerCrop()方法当中。那么我们就跟进去来看一下这个方法的源码,如下所示:

    public final class TransformationUtils {
        ...
    
        public static Bitmap centerCrop(Bitmap recycled, Bitmap toCrop, int width, int height) {
            if (toCrop == null) {
                return null;
            } else if (toCrop.getWidth() == width && toCrop.getHeight() == height) {
                return toCrop;
            }
            // From ImageView/Bitmap.createScaledBitmap.
            final float scale;
            float dx = 0, dy = 0;
            Matrix m = new Matrix();
            if (toCrop.getWidth() * height > width * toCrop.getHeight()) {
                scale = (float) height / (float) toCrop.getHeight();
                dx = (width - toCrop.getWidth() * scale) * 0.5f;
            } else {
                scale = (float) width / (float) toCrop.getWidth();
                dy = (height - toCrop.getHeight() * scale) * 0.5f;
            }
            m.setScale(scale, scale);
            m.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
    
            final Bitmap result;
            if (recycled != null) {
                result = recycled;
            } else {
                result = Bitmap.createBitmap(width, height, getSafeConfig(toCrop));
            }
    
            // We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given.
            TransformationUtils.setAlpha(toCrop, result);
    
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint(PAINT_FLAGS);
            canvas.drawBitmap(toCrop, m, paint);
            return result;
        }
    
        ...
    }

    这段代码就是整个图片变换功能的核心代码了。可以看到,第5-9行主要是先做了一些校验,如果原图为空,或者原图的尺寸和目标裁剪尺寸相同,那么就放弃裁剪。接下来第11-22行是通过数学计算来算出画布的缩放的比例以及偏移值。第24-29行是判断缓存池中取出的Bitmap对象是否为空,如果不为空就可以直接使用,如果为空则要创建一个新的Bitmap对象。第32行是将原图Bitmap对象的alpha值复制到裁剪Bitmap对象上面。最后第34-37行是裁剪Bitmap对象进行绘制,并将最终的结果进行返回。全部的逻辑就是这样,总体来说还是比较简单的,可能也就是数学计算那边需要稍微动下脑筋。

    那么现在得到了裁剪后的Bitmap对象,我们再回到CenterCrop当中,你会看到,在最终返回这个Bitmap对象之前,还会尝试将复用的Bitmap对象重新放回到缓存池当中,以便下次继续使用。

    好的,这样我们就将CenterCrop图片变换的工作原理完整地分析了一遍,FitCenter的源码也是基本类似的,这里就不再重复分析了。了解了这些内容之后,接下来我们就可以开始学习自定义图片变换功能了。

    自定义图片变换

    Glide给我们定制好了一个图片变换的框架,大致的流程是我们可以获取到原始的图片,然后对图片进行变换,再将变换完成后的图片返回给Glide,最终由Glide将图片显示出来。理论上,在对图片进行变换这个步骤中我们可以进行任何的操作,你想对图片怎么样都可以。包括圆角化、圆形化、黑白化、模糊化等等,甚至你将原图片完全替换成另外一张图都是可以的。

    但是这里显然我不可能向大家演示所有图片变换的可能,图片变换的可能性也是无限的。因此这里我们就选择一种常用的图片变换效果来进行自定义吧——对图片进行圆形化变换。

    图片圆形化的功能现在在手机应用中非常常见,比如手机QQ就会将用户的头像进行圆形化变换,从而使得界面变得更加好看。

    自定义图片变换功能的实现逻辑比较固定,我们刚才看过CenterCrop的源码之后,相信你已经基本了解整个自定义的过程了。其实就是自定义一个类让它继承自BitmapTransformation ,然后重写transform()方法,并在这里去实现具体的图片变换逻辑就可以了。一个空的图片变换实现大概如下所示:

    public class CircleCrop extends BitmapTransformation {
    
        public CircleCrop(Context context) {
            super(context);
        }
    
        public CircleCrop(BitmapPool bitmapPool) {
            super(bitmapPool);
        }
    
        @Override
        public String getId() {
            return "com.example.glidetest.CircleCrop";
        }
    
        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            return null;
        }
    }

    这里有一点需要注意,就是getId()方法中要求返回一个唯一的字符串来作为id,以和其他的图片变换做区分。通常情况下,我们直接返回当前类的完整类名就可以了。

    另外,这里我们选择继承BitmapTransformation还有一个限制,就是只能对静态图进行图片变换。当然,这已经足够覆盖日常95%以上的开发需求了。如果你有特殊的需求要对GIF图进行图片变换,那就得去自己实现Transformation接口才可以了。不过这个就非常复杂了,不在我们今天的讨论范围。

    好了,那么我们继续实现对图片进行圆形化变换的功能,接下来只需要在transform()方法中去做具体的逻辑实现就可以了,代码如下所示:

    public class CircleCrop extends BitmapTransformation {
    
        public CircleCrop(Context context) {
            super(context);
        }
    
        public CircleCrop(BitmapPool bitmapPool) {
            super(bitmapPool);
        }
    
        @Override
        public String getId() {
            return "com.example.glidetest.CircleCrop";
        }
    
        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            int diameter = Math.min(toTransform.getWidth(), toTransform.getHeight());
    
            final Bitmap toReuse = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888);
            final Bitmap result;
            if (toReuse != null) {
                result = toReuse;
            } else {
                result = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888);
            }
    
            int dx = (toTransform.getWidth() - diameter) / 2;
            int dy = (toTransform.getHeight() - diameter) / 2;
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            BitmapShader shader = new BitmapShader(toTransform, BitmapShader.TileMode.CLAMP, 
                                                BitmapShader.TileMode.CLAMP);
            if (dx != 0 || dy != 0) {
                Matrix matrix = new Matrix();
                matrix.setTranslate(-dx, -dy);
                shader.setLocalMatrix(matrix);
            }
            paint.setShader(shader);
            paint.setAntiAlias(true);
            float radius = diameter / 2f;
            canvas.drawCircle(radius, radius, radius, paint);
    
            if (toReuse != null && !pool.put(toReuse)) {
                toReuse.recycle();
            }
            return result;
        }
    }

    下面我来对transform()方法中的逻辑做下简单的解释。首先第18行先算出原图宽度和高度中较小的值,因为对图片进行圆形化变换肯定要以较小的那个值作为直径来进行裁剪。第20-26行则和刚才一样,从Bitmap缓存池中尝试获取一个Bitmap对象来进行重用,如果没有可重用的Bitmap对象的话就创建一个。第28-41行是具体进行圆形化变换的部分,这里算出了画布的偏移值,并且根据刚才得到的直径算出半径来进行画圆。最后,尝试将复用的Bitmap对象重新放回到缓存池当中,并将圆形化变换后的Bitmap对象进行返回。

    这样,一个自定义图片变换的功能就写好了,那么现在我们就来尝试使用一下它吧。使用方法非常简单,刚才已经介绍过了,就是把这个自定义图片变换的实例传入到transform()方法中即可,如下所示:

    Glide.with(this)
         .load(url)
         .transform(new CircleCrop(this))
         .into(imageView);

    现在我们重新运行一下程序,效果如下图所示。

    更多图片变换功能

    虽说Glide的图片变换功能框架已经很强大了,使得我们可以轻松地自定义图片变换效果,但是如果每一种图片变换都要我们自己去写还是蛮吃力的。事实上,确实也没有必要完全靠自己去实现各种各样的图片变换效果,因为大多数的图片变换都是比较通用的,各个项目会用到的效果都差不多,我们每一个都自己去重新实现无异于重复造轮子。

    也正是因此,网上出现了很多Glide的图片变换开源库,其中做的最出色的应该要数glide-transformations这个库了。它实现了很多通用的图片变换效果,如裁剪变换、颜色变换、模糊变换等等,使得我们可以非常轻松地进行各种各样的图片变换。

    glide-transformations的项目主页地址是 https://github.com/wasabeef/glide-transformations

    下面我们就来体验一下这个库的强大功能吧。首先需要将这个库引入到我们的项目当中,在app/build.gradle文件当中添加如下依赖:

    dependencies {
        compile 'jp.wasabeef:glide-transformations:2.0.2'
    }

    现在如果我想对图片进行模糊化处理,那么就可以使用glide-transformations库中的BlurTransformation这个类,代码如下所示:

    Glide.with(this)
         .load(url)
         .bitmapTransform(new BlurTransformation(this))
         .into(imageView);

    注意这里我们调用的是bitmapTransform()方法而不是transform()方法,因为glide-transformations库都是专门针对静态图片变换来进行设计的。现在重新运行一下程度,效果如下图所示。

    没错,我们就这样轻松地实现模糊化的效果了。

    接下来我们再试一下图片黑白化的效果,使用的是GrayscaleTransformation这个类,代码如下所示:

    Glide.with(this)
         .load(url)
         .bitmapTransform(new GrayscaleTransformation(this))
         .into(imageView);

    现在重新运行一下程度,效果如下图所示。

    而且我们还可以将多个图片变换效果组合在一起使用,比如同时执行模糊化和黑白化的变换:

    Glide.with(this)
         .load(url)
         .bitmapTransform(new BlurTransformation(this), new GrayscaleTransformation(this))
         .into(imageView);

    可以看到,同时执行多种图片变换的时候,只需要将它们都传入到bitmapTransform()方法中即可。现在重新运行一下程序,效果如下图所示。

    当然,这些只是glide-transformations库的一小部分功能而已,更多的图片变换效果你可以到它的GitHub项目主页去学习,所有变换的用法都是这么简单哦。

    好了,那么今天的文章就到这里了,相信大家的收获都很多吧。下篇文章中我们会继续深入探究Glide,学习一下自定义模块的功能,感兴趣的朋友请继续阅读 Android图片加载框架最全解析(六),探究Glide的自定义模块功能

    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

            

    展开全文
  • 大图片加载框架比较

    千次阅读 2016-07-19 18:12:44
    为什么图片加载我首先Glide 图片加载框架用了不少,从afinal框架的afinalBitmap,Xutils的BitmapUtils,老牌框架universalImageLoader,著名开源组织square的picasso,google推荐的glide到FaceBook推出的fresco。...
    为什么图片加载我首先想到Glide,
    图片加载框架用了不少,从afinal框架的afinalBitmap,Xutils的BitmapUtils,老牌框架universalImageLoader,著名开源组织square的picasso,google推荐的glide到FaceBook推出的fresco。这些我前前后后都体验过,那么面对这么多的框架,该如何选择呢?下面简单分析下我的看法。 
    

    afinal和Xuils在github上作者已经停止维护了,开源社区最新的框架要属KJFramework,不过这种快速开发框架看似很好用,功能也应有尽有,小型项目也罢,大型项目我不是很推荐,这样做项目的耦合度太高,一旦出现停止维护,而新的问题不断增加,没人处理就麻烦了。

    在glide和fresco还未出来的时候,当时最火的莫过于universalImageLoader和picasso了,当时觉得universalImageLoader配置相对picasso麻烦,虽然提供了各种配置,但是没有实践过,根本不知道如何配置,还不如都采用默认配置,就选择了picasso作为图片加载框架,用了近一年的时间,没有太大的问题,且使用简单,或许是因为之前的项目太过于简单,周期也并不是很长,还有使用eclipse开发,一个很大的问题一直都没有暴露出来,换上了最新的Android Studio可以清晰的看到各种性能相关的监控,如cpu还有内存监控,终于知道了之前做的项目都那么的卡顿的罪魁祸首,picasso加载稍微大一点的图片就特别耗内存,通常一个listView或者顶部滑动广告栏都含有多张图片,这使得做出的页面只要含图片较多就异常卡顿(之前的时候还把它归结为测试机不好),知道这一点后我就有点想把picasso给替换掉,但这一次我不能那么粗心。

    测试了picasso,glide,universalImageLoader,fresco这四个框架,测试内容大概有以下几项,内存测试,大图片测试,小图片测试,本地图片,网络图片当然还结合官方文档体验其特色功能,内存测试中,glide,universalImageLoader,fresco表现都非常优秀,picasso这一点上实在是太糟糕了,小图片差别也不是很大,稍微大点图片内存消耗就要比其他高出几倍,这一点上证明了我的猜想,picasso不能再用了,下面一项项分析其他框架,在高于2M左右大图测试中fresco的表现则和picasso一样直接神马都不显示,项目中要实现大图预览功能,这点上是不行的,接着看universalImageLoader和glide在这几项测试中成绩都很好,到底该如何选择呢?

    因为我项目之前用的picasso,glide从用法上几乎就是另一个picasso,从picasso转移到glide相对改动较少,还有一点就是这个项目是google在维护,我也能给它更多的信任,相比较universalImageLoader,glide可以支持gif和短视频,后期也需要用到,这里不得不谈一下glide优秀的缓存机制了,glide图片缓存默认使用RGB565相当于ARGB8888可以节省不少的空间,支持与activity,fragment,application生命周期的联动,更智能管理图片请求当然还有其他的扩展更多可以看 glide介绍 当然,glide的方法数量比universalImageLoader多了1000多个,遇到64k问题的会比较关注这个。

    刚才只是掠过fresco,其实我对他的期待还是蛮大的,因为刚出来还有居多不稳定的地方,里面存在着大量吸引着我的功能,支持webps格式(和jpg一样都是有损压缩格式,webps相同质量图片更节省空间),支持渐进式jpeg,可以轻松的定制image的各种属性,支持多图请求和图片复用,并支持手势缩放和旋转等等,更多介绍 fresco,当然,实际用的时候并没有那么好,很多功能都有待完善。

    还有一点细节的地方要注意的,最好不要直接拿来用,至少经过自己简单的封装,而不是直接在项目中使用,一个简单的例子,后期图片过多,可能需要另外配置一台机器单独存放图片,主机地址做成可配置,可不要因为一个简单的需求又要加班了

    展开全文
  • Java ZXing 生成QRCode二维码的两种方式,可设置图片大小,外白色边框大小。google的zxing project 是一个很棒的,几乎可以在所有平台(Android、JavaSE、iPhone、RIM、Symbian)中可以用来生成、解析QR码的开源库...

            Java ZXing 生成QRCode二维码的两种方式,可设置图片大小,和外白色边框大小。google的zxing project 是一个很棒的,几乎可以在所有平台(Android、JavaSE、iPhone、RIM、Symbian)中可以用来生成、解析QR码的开源库。

    QRGen在ZXing基础上开发,这个库使得利用Java生成QR码变为小菜一碟。它需要依赖ZXing,所以生成图案时你同时需要ZXing和QRGen的jar包。 

    QR 码最常见的应用便是为网站中一个特定的网页或下载页带来流量。因此,QR码常常会编码URL或网站地址,用户可以通过手机摄像头扫描,并在其浏览器中打开

    大多数时候,你需要在网站上动态的生成一些QR码。我们已经看到Java中生成QR码是多么的容易。现在,我们看看如何把生成QR码集成到Java Servlet中。



    具体设置方式我已经发表在我的个人站点里了。点击下边可查看


    版权属于: 技术客

    原文地址: https://www.sunjs.com/article/detail/960f292ddc824655b058920cb1ff58be.html

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。




    展开全文
  • 不能够自动的缩写编辑内大小一样,找了半天代码没发现怎么修改,它上传缩小,在config中 “imageCompressBorder”: 1600, /* 图片压缩 最长边限制 */没什么作用呢。最后还是被我找到了,下面我就来给大家说说...
  • 这两个缓存模块的作用各不相同,内存缓存的主要作用是防止应用重复将图片数据读取到内存当中,而硬盘缓存的主要作用是防止应用重复从网络或其他地方重复下载读取数据。 内存缓存硬盘缓存的相互结合才构成了...
  • 图片加载框架Glide解析

    万次阅读 多人点赞 2015-04-13 15:32:19
    Glide具有获取、解码展示视频剧照、图片、动画等功能,它还有灵活的API,这些API使开发者能够将Glide应用在几乎任何网络协议栈里。创建Glide的主要目的有两个,一个是实现平滑的图片列表滚动效果,另一个是支持...
  • 2:图层)(目前图层不支持组合后的图层,数据范围为所选图层范围,数据宽高和页面打印建议宽高会在输出结果中显示)如图:代码如下:#coding:gbk from __future__ import division __author__ = '杭州华耕_杨勇...
  • 对于刚刚接触EDIUS 8 这款非线性编辑软件的小伙伴来说,EDIUS8的很多功能是有待更深一步的了解并学习如何使用的,所以这里我将简单的介绍下如使用EDIUS 8处理图片素材添加的图片素材都一样大
  • /******最完美解决 图片在图片框内按宽高比例自动缩放!!!***/ //Img:要放图片的img元素,onload时传参可用this //maxHeight :img元素的高度,像素(图片框 最大高度) //maxWidth:img元素的宽度,像素(图片...
  • Android 给图片加边框

    万次阅读 2012-02-17 10:36:53
    将边框图片裁剪成八张小图片(图片大小最好一致,不然后面处理会很麻烦),分别对应左上角,左边,左下角,下边,右下角,右边,右上角,上边,其中左右上下只需要一个有效长度,就像重写水平进度条一样,只需要一个...
  • 图片加载框架Glide使用详解

    万次阅读 2016-07-16 03:20:39
    代码提交频率频繁,有人维护,不至于出现问题,我自己基友都搞不定的时候问题无法解决。(ImageLoader已没人维护了) 代码简洁,可读性很好。(Fresco是一个非常优秀的库,但是配置稍显麻烦,同时代码风格读起来...
  • 今天遇到一个需求,需要在一张图片上增加一个模板边框。初看这个需求还挺简单的,就是在一张目标图片上覆盖一张边框图嘛。 假如目标图片为 覆盖边框图片为 使用cv2实现的代码如下 import cv2 ak1=cv2....
  • 本篇将是我们这个Glide系列的最后一篇文章。 其实在写这个系列第一篇文章的时候,Glide就推出4.0.0的RC版了。那个时候因为我一直研究的都是Glide ...而且也不断有朋友一直在留言,想我讲一讲Glide 4的用法,因为Glid
  • 作为前端er,肯定碰到过将一组要将一组图标整齐排列的问题,图片一样大还好,不一样大的话,没经验还真是烦人呢。 如图,排列不整齐美观。为了方便你我他,我加了边框 如果粗暴的把图片设置为一样大小,那图片会...
  • Fresco图片框架内部实现原理探索

    万次阅读 多人点赞 2016-01-04 18:38:21
    流行的网络框架目前流行的网络图片框架: Picasso、Universal Image Loader、Volley的(ImageLoader、...其中PicassoUniversal Image Loader相比其它的算是最轻量级的图片框架了,它们拥有较少的方法数,Universal I
  • 图片加载框架Glide使用教程

    万次阅读 多人点赞 2016-01-02 20:42:01
    Glide已经被谷歌官方的应用程序所使用(如2015年的 Google I / O的应用程序),同时,它Picasso一样受到Android应用开发者的欢迎。在项目中引入GlideGradle:compile 'com.github.bumptech.glide:gl
  • Qt实现等待提示图片和movie实现) 上一篇文章说了怎样用代码实现等待提示,这篇文章来说一下怎么用切换图片或者播放gif图片来实现。
  • CSS 图片边框的处理

    千次阅读 2018-01-17 11:23:44
    一、边框高度固定,内容可滚动 这种情况下,直接将整个边框切下来作为背景图,里面的内容设置固定高度,溢出部分设置overflow... 转眼已经入冬了,时间太过迅驰,我我的南方小城一样,总是慢吞吞地跟不上时节的节奏。
  • 简单说下原理,把显示图片的img标签上传文件的 input标签放在同一个div下,input设置的大小img的大小一样, 设置透明度为0,用定位设置优先级把input浮动在img上方,这样点击图片就能弹出文件选择,选择完...
  • Fresco图片加载框架的介绍,相关开源库以及工具类的封装Fresco图片加载框架的介绍相关开源库以及工具类的封装 工具类FrescoUtils地址 简介 优点一内存管理 优点二更便捷的使用 相关文档及开源库 使用心得及一些方法的...
  • 我遇到的问题是这样的:   list要有图片,但是有的图片太长或者太宽,就...那么久出现一个问题就是背景图片解析不出来,显示空白。   解决方法: 使用img标签,有人会说img没法做到background-size: co...
  • 大家好,今天我们继续学习...今天是这个Glide系列的第四篇文章,我们又要选取一个新的功能模块开始学习了,那么就来研究一下Glide的回调监听功能吧。今天的学习模式仍然是以基本用法源码分析相结合的方式来进行的
  • 图片显示采用了image组件,设置image组件的scaleToFill模式(不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素) swiper布局代码: <view class="uni-margin-wrap"> <swiper class=...
  • 图片加载框架-Picasso最详细的使用指南

    万次阅读 多人点赞 2018-06-05 13:36:24
    写在前面Android 中有几个比较有名的图片加载框架,Universal ImageLoader、Picasso、GlideFresco。它们各有优点,以前一直用的是ImageLoader 做项目中的图片加载,由于作者宣布ImageLoader 不会在更新了,因此新...
  • 在Android开发中,常需要从远程获取图片并显示在客户端,当然我们可以使用原生HttpUrlConnectionAsyncTask等操作来完成,但并不推荐,因为这样不仅需要我们编写大量的代码,还需要处理缓存下载管理等,最好自己...
  • APICloud框架——获取本地图片信息

    千次阅读 2017-04-19 07:37:37
    获取本地图片放置到服务器上或者在app中预览是app的基本功能,今天使用了APICloud框架的api.getPicture这个api获取到的本地图片预览在app中,就像上传qq头像一样,其实就是这个需求,获取本地照片(拍摄照片)设置...
  • 在这半年中,我们通过用法讲解源码分析配合学习的方式,将Glide的方方面面都研究了个遍,相信一直能看到这里的朋友现在已经是一位Glide高手了。 整个Glide系列预计总共会有八篇文章,现在也是逐步进入尾声了。...
  • Fresco图片加载框架使用经验小结

    千次阅读 2016-08-24 09:43:31
    Fresco图片加载框架使用经验小结 原创 2016-08-23 hss01248 鸿洋 本文由hss01248投稿。 hss01248的博客地址: http://blog.csdn.net/hss01248 本文是作者在使用Fresco过程中一些经验分享,包含了大量的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 293,763
精华内容 117,505
关键字:

如何让图片和框一样大