Android笔记之(图片高斯+Glide实现微信图片加载策略+仿微信进度条)
来源:互联网 发布:复杂网络 newman 编辑:程序博客网 时间:2024/06/02 12:54
很久以前就想自己实现一下仿微信图片加载的那种策略了,先加载一张模糊的图片,然后再加载清晰大图,今天研究了一下,不过要是Glide支持进度条显示就好了,不得不说Glide很强大,
不啰嗦了,直接上代码了。
首先看看高斯模糊到底怎么实现,你问我我也不会(^__^) 嘻嘻……,直接附上网上的算法:
package com.cisetech.dialogdemo;import android.graphics.Bitmap;/** * Author:Yqy * Date:2016-09-29 * Desc: * Company:cisetech */public class FastBlur { public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { // Stack Blur v1.0 from // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html // // Java Author: Mario Klingemann <mario at quasimondo.com> // http://incubator.quasimondo.com // created Feburary 29, 2004 // Android port : Yahel Bouaziz <yahel at kayenko.com> // http://www.kayenko.com // ported april 5th, 2012 // This is a compromise between Gaussian Blur and Box blur // It creates much better looking blurs than Box Blur, but is // 7x faster than my Gaussian Blur implementation. // // I called it Stack Blur because this describes best how this // filter works internally: it creates a kind of moving stack // of colors whilst scanning through the image. Thereby it // just has to add one new block of color to the right side // of the stack and remove the leftmost color. The remaining // colors on the topmost layer of the stack are either added on // or reduced by one, depending on if they are on the right or // on the left side of the stack. // // If you are using this algorithm in your code please add // the following line: // // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> Bitmap bitmap; if (canReuseInBitmap) { bitmap = sentBitmap; } else { bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); } if (radius < 1) { return (null); } int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w * h]; bitmap.getPixels(pix, 0, w, 0, 0, w, h); int wm = w - 1; int hm = h - 1; int wh = w * h; int div = radius + radius + 1; int r[] = new int[wh]; int g[] = new int[wh]; int b[] = new int[wh]; int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; int vmin[] = new int[Math.max(w, h)]; int divsum = (div + 1) >> 1; divsum *= divsum; int dv[] = new int[256 * divsum]; for (i = 0; i < 256 * divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; int[][] stack = new int[div][3]; int stackpointer; int stackstart; int[] sir; int rbs; int r1 = radius + 1; int routsum, goutsum, boutsum; int rinsum, ginsum, binsum; for (y = 0; y < h; y++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; for (i = -radius; i <= radius; i++) { p = pix[yi + Math.min(wm, Math.max(i, 0))]; sir = stack[i + radius]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rbs = r1 - Math.abs(i); rsum += sir[0] * rbs; gsum += sir[1] * rbs; bsum += sir[2] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } } stackpointer = radius; for (x = 0; x < w; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (y == 0) { vmin[x] = Math.min(x + radius + 1, wm); } p = pix[yw + vmin[x]]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[(stackpointer) % div]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi++; } yw += w; } for (x = 0; x < w; x++) { rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0; yp = -radius * w; for (i = -radius; i <= radius; i++) { yi = Math.max(0, yp) + x; sir = stack[i + radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; rbs = r1 - Math.abs(i); rsum += r[yi] * rbs; gsum += g[yi] * rbs; bsum += b[yi] * rbs; if (i > 0) { rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; } else { routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; } if (i < hm) { yp += w; } } yi = x; stackpointer = radius; for (y = 0; y < h; y++) { // Preserve alpha channel: ( 0xff000000 & pix[yi] ) pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]; rsum -= routsum; gsum -= goutsum; bsum -= boutsum; stackstart = stackpointer - radius + div; sir = stack[stackstart % div]; routsum -= sir[0]; goutsum -= sir[1]; boutsum -= sir[2]; if (x == 0) { vmin[y] = Math.min(y + r1, hm) * w; } p = x + vmin[y]; sir[0] = r[p]; sir[1] = g[p]; sir[2] = b[p]; rinsum += sir[0]; ginsum += sir[1]; binsum += sir[2]; rsum += rinsum; gsum += ginsum; bsum += binsum; stackpointer = (stackpointer + 1) % div; sir = stack[stackpointer]; routsum += sir[0]; goutsum += sir[1]; boutsum += sir[2]; rinsum -= sir[0]; ginsum -= sir[1]; binsum -= sir[2]; yi += w; } } bitmap.setPixels(pix, 0, w, 0, 0, w, h); return (bitmap); }}
由于代码比较少,我就直接全部粘贴了,可以直接拿去研究额。
package com.cisetech.dialogdemo;import android.app.Dialog;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.WindowManager;import android.widget.ImageView;import android.widget.ProgressBar;import com.bumptech.glide.Glide;import com.bumptech.glide.load.engine.DiskCacheStrategy;import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;import com.bumptech.glide.load.resource.drawable.GlideDrawable;import com.bumptech.glide.request.RequestListener;import com.bumptech.glide.request.target.Target;public class MainActivity extends AppCompatActivity { private int screenWidth; private ImageView id_iv; private ProgressBar pb; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); WindowManager wm=getWindowManager(); DisplayMetrics outMetrics=new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); screenWidth=outMetrics.widthPixels; id_iv= (ImageView) findViewById(R.id.id_iv); pb= (ProgressBar) findViewById(R.id.pb); Glide.with(this).load("http://img0.bdstatic.com/img/image/shouye/xinshouye/dongman928.jpg") .centerCrop() .listener(new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String s, Target<GlideDrawable> target, boolean b) { return false; } @Override public boolean onResourceReady(final GlideDrawable glideDrawable, String s, Target<GlideDrawable> target, boolean b, boolean b1) { Log.e("TAG", "onResourceReady: target-------->"+target ); Log.e("TAG", "onResourceReady: glideDrawable-------->"+glideDrawable ); Glide.with(MainActivity.this).load("http://img0.bdstatic.com/img/image/shouye/xinshouye/dongman928.jpg"). centerCrop().placeholder(glideDrawable). diskCacheStrategy(DiskCacheStrategy.NONE). skipMemoryCache(true).dontAnimate(). crossFade(1000). listener(new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String s, Target<GlideDrawable> target, boolean b) { return false; } @Override public boolean onResourceReady(GlideDrawable glideDrawable, String s, Target<GlideDrawable> target, boolean b, boolean b1) { pb.setVisibility(View.GONE); return false; } }). into(id_iv); return false; } }). transform(new MyTransformtion(this)). diskCacheStrategy(DiskCacheStrategy.ALL). placeholder(new ColorDrawable(Color.BLACK)) .dontAnimate().into(id_iv); //createLoadingDialog(this).show(); } public Dialog createLoadingDialog(Context context) { LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(R.layout.wechat_dialog, null);// 得到加载view Dialog loadingDialog = new Dialog(context, R.style.loading_dialog);// 创建自定义样式dialog loadingDialog.setCancelable(false);// 不可以用“返回键”取消 loadingDialog.setContentView(v);// 设置布局 /** * 设置Dialog的宽度为屏幕宽度的61.8%,高度为自适应 */ WindowManager.LayoutParams lp = loadingDialog.getWindow().getAttributes(); lp.width= (int) (screenWidth*0.618f); lp.height=lp.WRAP_CONTENT; loadingDialog.getWindow().setAttributes(lp); return loadingDialog; } public class MyTransformtion extends BitmapTransformation{ public MyTransformtion(Context context) { super(context); } @Override protected Bitmap transform(BitmapPool bitmapPool, Bitmap bitmap, int i, int i1) { Log.e("TAG", "transform: bitmap-------->"+bitmap ); return FastBlur.doBlur(bitmap,10,true); } @Override public String getId() { return "com.cisetech.dialogdemo.MyTransformtion"; } }}
仿微信进度条可以看我另外一篇博客Android进阶之(Dailog详解),这里写在一个工程里面了,我就直接贴代码了。
源码链接:http://pan.baidu.com/s/1gflwaFx
0 0
- Android笔记之(图片高斯+Glide实现微信图片加载策略+仿微信进度条)
- 使用Glide模仿微信图片加载策略
- android笔记-glide加载图片
- Android之Glide加载图片
- 图片加载之glide
- Glide之加载图片
- Android Glide 图片加载
- Android 流行的网络图片加载库 之 使用 Glide 加载图片 (Google推荐的图片加载库Glide)
- Android学习之图片加载库Glide
- 【Android 进阶】图片加载框架之Glide
- 【Android 进阶】图片加载框架之Glide
- Android开发之图片加载框架Glide
- Android开发之图片加载~初识Glide
- 初识Android图片加载之Glide
- Android图片加载之Glide使用
- 【Android】开发干货-技术分享之高仿QQ微信网页加载进度条实现
- Android之Glide(非常好用的图片加载框架)
- Android之Glide(非常好用的图片加载框架)
- Android Service演义
- etcd 使用入门
- RXJava 简介
- Java面试题大全(流行的框架部分)
- 二分法查找
- Android笔记之(图片高斯+Glide实现微信图片加载策略+仿微信进度条)
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- bootstrap table里th设置data-width="400px"后,发现url不能适应,th突破限制。
- Java学习笔记(二十三):将InputStream转成字符串和写入文件
- 【Salesforce】地理位置情報項目を使って周辺検索 GMaps
- ServletContext简单介绍
- c++中的初始化列表
- RxBus完全一样的 EventBus
- C++单调队列入门