Android本地图片或者网络图片高斯模糊效果(毛玻璃效果)图片模糊效果一行代码搞定

来源:互联网 发布:优化营商环境重要意义 编辑:程序博客网 时间:2024/05/15 12:17

本地图片或者网络图片高斯模糊效果(毛玻璃效果)

首先看效果图
1,本地图片高斯模糊


2,网络图片高斯模糊



github网址:https://github.com/qiushi123/BlurImageQcl



下面是使用步骤

一,实现本地图片或者网络图片的毛玻璃效果特别方便,只需要把下面的FastBlurUtil类复制到你的项目中就行

[java] view plain copy 
 在CODE上查看代码片派生到我的代码片
  1. package com.testdemo.blur_image_lib10;  
  2.   
  3.   
  4. import android.graphics.Bitmap;  
  5. import android.graphics.BitmapFactory;  
  6.   
  7.   
  8. import java.io.BufferedInputStream;  
  9. import java.io.BufferedOutputStream;  
  10. import java.io.ByteArrayOutputStream;  
  11. import java.io.IOException;  
  12. import java.io.InputStream;  
  13. import java.io.OutputStream;  
  14. import java.net.URL;  
  15.   
  16.   
  17. /** 
  18.  * Created by qcl on 14/7/15. 
  19.  */  
  20. public class FastBlurUtil {  
  21.     /** 
  22.      * 根据imagepath获取bitmap 
  23.      */  
  24.     /** 
  25.      * 得到本地或者网络上的bitmap url - 网络或者本地图片的绝对路径,比如: 
  26.      * <p> 
  27.      * A.网络路径: url="http://blog.foreverlove.us/girl2.png" ; 
  28.      * <p> 
  29.      * B.本地路径:url="file://mnt/sdcard/photo/image.png"; 
  30.      * <p> 
  31.      * C.支持的图片格式 ,png, jpg,bmp,gif等等 
  32.      * 
  33.      * @param url 
  34.      * @return 
  35.      */  
  36.     public static int IO_BUFFER_SIZE = 2 * 1024;  
  37.   
  38.   
  39.     public static Bitmap GetUrlBitmap(String url, int scaleRatio) {  
  40.   
  41.   
  42.         int blurRadius = 8;//通常设置为8就行。  
  43.         if (scaleRatio <= 0) {  
  44.             scaleRatio = 10;  
  45.         }  
  46.   
  47.   
  48.   
  49.   
  50.         Bitmap originBitmap = null;  
  51.         InputStream in = null;  
  52.         BufferedOutputStream out = null;  
  53.         try {  
  54.             in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);  
  55.             final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();  
  56.             out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);  
  57.             copy(in, out);  
  58.             out.flush();  
  59.             byte[] data = dataStream.toByteArray();  
  60.             originBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
  61.   
  62.   
  63.             Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,  
  64.                     originBitmap.getWidth() / scaleRatio,  
  65.                     originBitmap.getHeight() / scaleRatio,  
  66.                     false);  
  67.             Bitmap blurBitmap = doBlur(scaledBitmap, blurRadius, true);  
  68.             return blurBitmap;  
  69.         } catch (IOException e) {  
  70.             e.printStackTrace();  
  71.             return null;  
  72.         }  
  73.     }  
  74.   
  75.   
  76.     private static void copy(InputStream in, OutputStream out)  
  77.             throws IOException {  
  78.         byte[] b = new byte[IO_BUFFER_SIZE];  
  79.         int read;  
  80.         while ((read = in.read(b)) != -1) {  
  81.             out.write(b, 0, read);  
  82.         }  
  83.     }  
  84.   
  85.   
  86.   
  87.   
  88.     //    把本地图片毛玻璃化  
  89.     public static Bitmap toBlur(Bitmap originBitmap, int scaleRatio) {  
  90.         //        int scaleRatio = 10;  
  91.         // 增大scaleRatio缩放比,使用一样更小的bitmap去虚化可以到更好的得模糊效果,而且有利于占用内存的减小;  
  92.         int blurRadius = 8;//通常设置为8就行。  
  93.         //增大blurRadius,可以得到更高程度的虚化,不过会导致CPU更加intensive  
  94.   
  95.   
  96.        /* 其中前三个参数很明显,其中宽高我们可以选择为原图尺寸的1/10; 
  97.         第四个filter是指缩放的效果,filter为true则会得到一个边缘平滑的bitmap, 
  98.         反之,则会得到边缘锯齿、pixelrelated的bitmap。 
  99.         这里我们要对缩放的图片进行虚化,所以无所谓边缘效果,filter=false。*/  
  100.         if (scaleRatio <= 0) {  
  101.             scaleRatio = 10;  
  102.         }  
  103.         Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,  
  104.                 originBitmap.getWidth() / scaleRatio,  
  105.                 originBitmap.getHeight() / scaleRatio,  
  106.                 false);  
  107.         Bitmap blurBitmap = doBlur(scaledBitmap, blurRadius, true);  
  108.         return blurBitmap;  
  109.     }  
  110.   
  111.   
  112.     public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {  
  113.         Bitmap bitmap;  
  114.         if (canReuseInBitmap) {  
  115.             bitmap = sentBitmap;  
  116.         } else {  
  117.             bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);  
  118.         }  
  119.   
  120.   
  121.         if (radius < 1) {  
  122.             return (null);  
  123.         }  
  124.   
  125.   
  126.         int w = bitmap.getWidth();  
  127.         int h = bitmap.getHeight();  
  128.   
  129.   
  130.         int[] pix = new int[w * h];  
  131.         bitmap.getPixels(pix, 0, w, 00, w, h);  
  132.   
  133.   
  134.         int wm = w - 1;  
  135.         int hm = h - 1;  
  136.         int wh = w * h;  
  137.         int div = radius + radius + 1;  
  138.   
  139.   
  140.         int r[] = new int[wh];  
  141.         int g[] = new int[wh];  
  142.         int b[] = new int[wh];  
  143.         int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;  
  144.         int vmin[] = new int[Math.max(w, h)];  
  145.   
  146.   
  147.         int divsum = (div + 1) >> 1;  
  148.         divsum *= divsum;  
  149.         int dv[] = new int[256 * divsum];  
  150.         for (i = 0; i < 256 * divsum; i++) {  
  151.             dv[i] = (i / divsum);  
  152.         }  
  153.   
  154.   
  155.         yw = yi = 0;  
  156.   
  157.   
  158.         int[][] stack = new int[div][3];  
  159.         int stackpointer;  
  160.         int stackstart;  
  161.         int[] sir;  
  162.         int rbs;  
  163.         int r1 = radius + 1;  
  164.         int routsum, goutsum, boutsum;  
  165.         int rinsum, ginsum, binsum;  
  166.   
  167.   
  168.         for (y = 0; y < h; y++) {  
  169.             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  170.             for (i = -radius; i <= radius; i++) {  
  171.                 p = pix[yi + Math.min(wm, Math.max(i, 0))];  
  172.                 sir = stack[i + radius];  
  173.                 sir[0] = (p & 0xff0000) >> 16;  
  174.                 sir[1] = (p & 0x00ff00) >> 8;  
  175.                 sir[2] = (p & 0x0000ff);  
  176.                 rbs = r1 - Math.abs(i);  
  177.                 rsum += sir[0] * rbs;  
  178.                 gsum += sir[1] * rbs;  
  179.                 bsum += sir[2] * rbs;  
  180.                 if (i > 0) {  
  181.                     rinsum += sir[0];  
  182.                     ginsum += sir[1];  
  183.                     binsum += sir[2];  
  184.                 } else {  
  185.                     routsum += sir[0];  
  186.                     goutsum += sir[1];  
  187.                     boutsum += sir[2];  
  188.                 }  
  189.             }  
  190.             stackpointer = radius;  
  191.   
  192.   
  193.             for (x = 0; x < w; x++) {  
  194.   
  195.   
  196.                 r[yi] = dv[rsum];  
  197.                 g[yi] = dv[gsum];  
  198.                 b[yi] = dv[bsum];  
  199.   
  200.   
  201.                 rsum -= routsum;  
  202.                 gsum -= goutsum;  
  203.                 bsum -= boutsum;  
  204.   
  205.   
  206.                 stackstart = stackpointer - radius + div;  
  207.                 sir = stack[stackstart % div];  
  208.   
  209.   
  210.                 routsum -= sir[0];  
  211.                 goutsum -= sir[1];  
  212.                 boutsum -= sir[2];  
  213.   
  214.   
  215.                 if (y == 0) {  
  216.                     vmin[x] = Math.min(x + radius + 1, wm);  
  217.                 }  
  218.                 p = pix[yw + vmin[x]];  
  219.   
  220.   
  221.                 sir[0] = (p & 0xff0000) >> 16;  
  222.                 sir[1] = (p & 0x00ff00) >> 8;  
  223.                 sir[2] = (p & 0x0000ff);  
  224.   
  225.   
  226.                 rinsum += sir[0];  
  227.                 ginsum += sir[1];  
  228.                 binsum += sir[2];  
  229.   
  230.   
  231.                 rsum += rinsum;  
  232.                 gsum += ginsum;  
  233.                 bsum += binsum;  
  234.   
  235.   
  236.                 stackpointer = (stackpointer + 1) % div;  
  237.                 sir = stack[(stackpointer) % div];  
  238.   
  239.   
  240.                 routsum += sir[0];  
  241.                 goutsum += sir[1];  
  242.                 boutsum += sir[2];  
  243.   
  244.   
  245.                 rinsum -= sir[0];  
  246.                 ginsum -= sir[1];  
  247.                 binsum -= sir[2];  
  248.   
  249.   
  250.                 yi++;  
  251.             }  
  252.             yw += w;  
  253.         }  
  254.         for (x = 0; x < w; x++) {  
  255.             rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;  
  256.             yp = -radius * w;  
  257.             for (i = -radius; i <= radius; i++) {  
  258.                 yi = Math.max(0, yp) + x;  
  259.   
  260.   
  261.                 sir = stack[i + radius];  
  262.   
  263.   
  264.                 sir[0] = r[yi];  
  265.                 sir[1] = g[yi];  
  266.                 sir[2] = b[yi];  
  267.   
  268.   
  269.                 rbs = r1 - Math.abs(i);  
  270.   
  271.   
  272.                 rsum += r[yi] * rbs;  
  273.                 gsum += g[yi] * rbs;  
  274.                 bsum += b[yi] * rbs;  
  275.   
  276.   
  277.                 if (i > 0) {  
  278.                     rinsum += sir[0];  
  279.                     ginsum += sir[1];  
  280.                     binsum += sir[2];  
  281.                 } else {  
  282.                     routsum += sir[0];  
  283.                     goutsum += sir[1];  
  284.                     boutsum += sir[2];  
  285.                 }  
  286.   
  287.   
  288.                 if (i < hm) {  
  289.                     yp += w;  
  290.                 }  
  291.             }  
  292.             yi = x;  
  293.             stackpointer = radius;  
  294.             for (y = 0; y < h; y++) {  
  295.                 // Preserve alpha channel: ( 0xff000000 & pix[yi] )  
  296.                 pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];  
  297.   
  298.   
  299.                 rsum -= routsum;  
  300.                 gsum -= goutsum;  
  301.                 bsum -= boutsum;  
  302.   
  303.   
  304.                 stackstart = stackpointer - radius + div;  
  305.                 sir = stack[stackstart % div];  
  306.   
  307.   
  308.                 routsum -= sir[0];  
  309.                 goutsum -= sir[1];  
  310.                 boutsum -= sir[2];  
  311.   
  312.   
  313.                 if (x == 0) {  
  314.                     vmin[y] = Math.min(y + r1, hm) * w;  
  315.                 }  
  316.                 p = x + vmin[y];  
  317.   
  318.   
  319.                 sir[0] = r[p];  
  320.                 sir[1] = g[p];  
  321.                 sir[2] = b[p];  
  322.   
  323.   
  324.                 rinsum += sir[0];  
  325.                 ginsum += sir[1];  
  326.                 binsum += sir[2];  
  327.   
  328.   
  329.                 rsum += rinsum;  
  330.                 gsum += ginsum;  
  331.                 bsum += binsum;  
  332.   
  333.   
  334.                 stackpointer = (stackpointer + 1) % div;  
  335.                 sir = stack[stackpointer];  
  336.   
  337.   
  338.                 routsum += sir[0];  
  339.                 goutsum += sir[1];  
  340.                 boutsum += sir[2];  
  341.   
  342.   
  343.                 rinsum -= sir[0];  
  344.                 ginsum -= sir[1];  
  345.                 binsum -= sir[2];  
  346.   
  347.   
  348.                 yi += w;  
  349.             }  
  350.         }  
  351.   
  352.   
  353.         bitmap.setPixels(pix, 0, w, 00, w, h);  
  354.   
  355.   
  356.         return (bitmap);  
  357.     }  
  358.   
  359.   
  360. }  



二,==============使用实例=================================================================
[java] view plain copy 
 在CODE上查看代码片派生到我的代码片
  1. <span style="white-space:pre">    </span>package com.testdemo;  
  2.   
  3.     import android.app.Activity;  
  4.     import android.content.res.Resources;  
  5.     import android.graphics.Bitmap;  
  6.     import android.graphics.BitmapFactory;  
  7.     import android.os.Bundle;  
  8.     import android.text.TextUtils;  
  9.     import android.view.View;  
  10.     import android.widget.EditText;  
  11.     import android.widget.ImageView;  
  12.   
  13.     import com.testdemo.blur_image_lib10.FastBlurUtil;  
  14.   
  15.     public class MainActivity10_BlurImage extends Activity {  
  16.         ImageView image;  
  17.         EditText edit;  
  18.   
  19.         @Override  
  20.         protected void onCreate(Bundle savedInstanceState) {  
  21.             super.onCreate(savedInstanceState);  
  22.             setContentView(R.layout.activity_main10_blur_image);  
  23.             image = (ImageView) findViewById(R.id.image);  
  24.             edit = (EditText) findViewById(R.id.edit);  
  25.   
  26.   
  27.             findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {  
  28.                 @Override  
  29.                 public void onClick(View v) {  
  30.                     String pattern = edit.getText().toString();  
  31.                     int scaleRatio = 0;  
  32.                     if (TextUtils.isEmpty(pattern)) {  
  33.                         scaleRatio = 0;  
  34.                     } else if (scaleRatio < 0) {  
  35.                         scaleRatio = 10;  
  36.                     } else {  
  37.                         scaleRatio = Integer.parseInt(pattern);  
  38.                     }  
  39.   
  40.                     //        获取需要被模糊的原图bitmap  
  41.                     Resources res = getResources();  
  42.                     Bitmap scaledBitmap = BitmapFactory.decodeResource(res, R.drawable.filter);  
  43.   
  44.                     //        scaledBitmap为目标图像,10是缩放的倍数(越大模糊效果越高)  
  45.                     Bitmap blurBitmap = FastBlurUtil.toBlur(scaledBitmap, scaleRatio);  
  46.                     image.setScaleType(ImageView.ScaleType.CENTER_CROP);  
  47.                     image.setImageBitmap(blurBitmap);  
  48.                 }  
  49.             });  
  50.   
  51.             findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {  
  52.                 @Override  
  53.                 public void onClick(View v) {  
  54.                     //url为网络图片的url,10 是缩放的倍数(越大模糊效果越高)  
  55.                     final String pattern = edit.getText().toString();  
  56.   
  57.                     final String url =  
  58.                             //                        "http://imgs.duwu.me/duwu/doc/cover/201601/18/173040803962.jpg";  
  59.                             "http://b.hiphotos.baidu.com/album/pic/item/caef76094b36acafe72d0e667cd98d1000e99c5f.jpg?psign=e72d0e667cd98d1001e93901213fb80e7aec54e737d1b867";  
  60.                     new Thread(new Runnable() {  
  61.                         @Override  
  62.                         public void run() {  
  63.                             int scaleRatio = 0;  
  64.                             if (TextUtils.isEmpty(pattern)) {  
  65.                                 scaleRatio = 0;  
  66.                             } else if (scaleRatio < 0) {  
  67.                                 scaleRatio = 10;  
  68.                             } else {  
  69.                                 scaleRatio = Integer.parseInt(pattern);  
  70.                             }  
  71.     //                        下面的这个方法必须在子线程中执行  
  72.                             final Bitmap blurBitmap2 = FastBlurUtil.GetUrlBitmap(url, scaleRatio);  
  73.                               
  74.     //                        刷新ui必须在主线程中执行  
  75.                              APP.runOnUIThread(new Runnable() {//这个是我自己封装的在主线程中刷新ui的方法。  
  76.                                 @Override  
  77.                                 public void run() {  
  78.                                     image.setScaleType(ImageView.ScaleType.CENTER_CROP);  
  79.                                     image.setImageBitmap(blurBitmap2);  
  80.   
  81.                                 }  
  82.                             });  
  83.                         }  
  84.                     }).start();  
  85.   
  86.   
  87.                 }  
  88.             });  
  89.   
  90.   
  91.         }  
  92.   
  93.     }  
  94.       

=========下面是上面的布局文件======================================================================
[html] view plain copy 
 在CODE上查看代码片派生到我的代码片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.  xmlns:tools="http://schemas.android.com/tools"  
  3.  android:layout_width="match_parent"  
  4.  android:layout_height="match_parent"  
  5.  android:orientation="vertical">  
  6.   
  7.   
  8. <ImageView  
  9. android:id="@+id/image2"  
  10. android:layout_width="match_parent"  
  11. android:layout_height="220dp"  
  12. android:background="@drawable/filter"/>  
  13.   
  14.   
  15. <LinearLayout  
  16. android:layout_width="match_parent"  
  17. android:layout_height="wrap_content"  
  18. android:orientation="horizontal">  
  19.   
  20.   
  21. <EditText  
  22. android:id="@+id/edit"  
  23. android:layout_width="wrap_content"  
  24. android:layout_height="wrap_content"  
  25. android:layout_marginTop="15dp"  
  26. android:hint="输入模糊度"  
  27. />  
  28.   
  29.   
  30. <Button  
  31. android:id="@+id/button2"  
  32. android:layout_width="wrap_content"  
  33. android:layout_height="wrap_content"  
  34. android:text="转化毛玻璃"/>  
  35.   
  36.   
  37. <Button  
  38. android:id="@+id/button"  
  39. android:layout_width="wrap_content"  
  40. android:layout_height="wrap_content"  
  41. android:layout_marginLeft="4dp"  
  42. android:text="转化网络图片毛玻璃"/>  
  43. </LinearLayout>  
  44.   
  45.   
  46. <ImageView  
  47. android:id="@+id/image"  
  48. android:layout_width="match_parent"  
  49. android:layout_height="220dp"  
  50. android:layout_below="@+id/image2"  
  51. />  
  52. </LinearLayout>  



三,注意事项
1,一定不要忘记intent权限
2,加载网络图片时一定要在子线程中执行。


github网址:https://github.com/qiushi123/BlurImageQcl

阅读全文
0 0
原创粉丝点击