- 浏览: 1321046 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (132)
- android Launcher (15)
- 收藏夹 (3)
- UI设计 (28)
- J2EE (2)
- android网络编程 (8)
- 项目经理是熬出来的 (8)
- Android图像处理 (5)
- 系统层开发 (12)
- 数据库 (2)
- 程序员是熬出来的 (2)
- Android技巧 (11)
- 地图相关 (2)
- Android底层 (9)
- Android疑难杂症 (4)
- 开发工具 (4)
- 知识梳理 (8)
- 源码阅读 (7)
- Media媒体库 (5)
- 调试技术 (3)
- Android蓝牙 (3)
- 动画特效 (5)
- jni (3)
- 串口通信 (1)
- Android优化 (3)
- 架构设计 (1)
- Android Test (1)
- 翻译系列 (0)
最新评论
-
我说123木头人雪雪:
...
Android截屏并对图片做高斯模糊处理 -
ysc123shift:
没有源码。
Android截屏并对图片做高斯模糊处理 -
我de专属doll:
你那个Jni库是自己编译的还是有现成的呢?
Android media媒体库分析之:分类别统计媒体文件大小 -
zhunanfengfeimeng:
想做项目经理?这些工具必须了解 -
ls0609:
一个带人脸识别的智能照相机demohttp://blog.cs ...
Android 调用相机,获取的图片太小
这几天项目中需要模仿一下iOS版本的微博菜单弹出界面,如下图:
用微博的同学都知道这个效果吧,这篇文章先实现模糊效果,进入、退出动画后面文章分析;
一、说一下实现思路,很简单的:
1、截图:就是获取我们app得截图
获取我们Activity得根view即DecorView,关于DecorView,sdk里面是这么说明的:
就是说获取最顶层的window,可以添加到window manager里面;
拿到view之后可以调用view的getDrawingCache方法获取bitmap截图;
2、对图片做高斯模糊;
高斯模糊在Photoshop里面用的比较多,可以用来去痘痘。
大致原理是:对指定像素和其周围像素进行加权平均来得到最终结果,使用高斯分布作为滤波器。
这儿可以了解详细的算法原理:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html
二、代码实现:
代码比较简单,我自己加了注释贴出来了:
我这里用了外国开源项目中的一个Java算法,地址:https://github.com/paveldudka/blurring
如果用C/C++实现jni调用,效果会高一些,可以参考:https://github.com/qiujuer/ImageBlurring/blob/master/README-ZH.md
最后来一张屌丝做demo专业效果图:
全部代码见http://gqdy365.iteye.com/admin/blogs/2199256;
用微博的同学都知道这个效果吧,这篇文章先实现模糊效果,进入、退出动画后面文章分析;
一、说一下实现思路,很简单的:
1、截图:就是获取我们app得截图
获取我们Activity得根view即DecorView,关于DecorView,sdk里面是这么说明的:
Retrieve the top-level window decor view (containing the standard window frame/decorations and the client's content inside of that), which can be added as a window to the window manager.
就是说获取最顶层的window,可以添加到window manager里面;
拿到view之后可以调用view的getDrawingCache方法获取bitmap截图;
2、对图片做高斯模糊;
高斯模糊在Photoshop里面用的比较多,可以用来去痘痘。
大致原理是:对指定像素和其周围像素进行加权平均来得到最终结果,使用高斯分布作为滤波器。
这儿可以了解详细的算法原理:http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html
二、代码实现:
代码比较简单,我自己加了注释贴出来了:
private void applyBlur() { View view = getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(true); /** * 获取当前窗口快照,相当于截屏 */ Bitmap bmp1 = view.getDrawingCache(); int height = getOtherHeight(); /** * 除去状态栏和标题栏 */ Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, height,bmp1.getWidth(), bmp1.getHeight() - height); blur(bmp2, text); } @SuppressLint("NewApi") private void blur(Bitmap bkg, View view) { long startMs = System.currentTimeMillis(); float scaleFactor = 8;//图片缩放比例; float radius = 20;//模糊程度 Bitmap overlay = Bitmap.createBitmap( (int) (view.getMeasuredWidth() / scaleFactor), (int) (view.getMeasuredHeight() / scaleFactor), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(overlay); canvas.translate(-view.getLeft() / scaleFactor, -view.getTop()/ scaleFactor); canvas.scale(1 / scaleFactor, 1 / scaleFactor); Paint paint = new Paint(); paint.setFlags(Paint.FILTER_BITMAP_FLAG); canvas.drawBitmap(bkg, 0, 0, paint); overlay = FastBlur.doBlur(overlay, (int) radius, true); view.setBackground(new BitmapDrawable(getResources(), overlay)); /** * 打印高斯模糊处理时间,如果时间大约16ms,用户就能感到到卡顿,时间越长卡顿越明显,如果对模糊完图片要求不高,可是将scaleFactor设置大一些。 */ Log.i("jerome", "blur time:" + (System.currentTimeMillis() - startMs)); } /** * 获取系统状态栏和软件标题栏,部分软件没有标题栏,看自己软件的配置; * @return */ private int getOtherHeight() { Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); int titleBarHeight = contentTop - statusBarHeight; return statusBarHeight + titleBarHeight; }
我这里用了外国开源项目中的一个Java算法,地址:https://github.com/paveldudka/blurring
package com.jerome.popdemo; import android.graphics.Bitmap; /** * Created by paveld on 3/6/14. */ public class FastBlur { public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) { 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); } }
如果用C/C++实现jni调用,效果会高一些,可以参考:https://github.com/qiujuer/ImageBlurring/blob/master/README-ZH.md
/************************************************* Copyright: Copyright QIUJUER 2013. Author: Qiujuer Date: 2014-04-18 Description:实现图片模糊处理 **************************************************/ #include<malloc.h> #define ABS(a) ((a)<(0)?(-a):(a)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b)) /************************************************* Function: StackBlur(堆栈模糊) Description: 使用堆栈方式进行图片像素模糊处理 Calls: malloc Table Accessed: NULL Table Updated: NULL Input: 像素点集合,图片宽,图片高,模糊半径 Output: 返回模糊后的像素点集合 Return: 返回模糊后的像素点集合 Others: NULL *************************************************/ static int* StackBlur(int* pix, int w, int h, int radius) { int wm = w - 1; int hm = h - 1; int wh = w * h; int div = radius + radius + 1; int *r = (int *)malloc(wh * sizeof(int)); int *g = (int *)malloc(wh * sizeof(int)); int *b = (int *)malloc(wh * sizeof(int)); int rsum, gsum, bsum, x, y, i, p, yp, yi, yw; int *vmin = (int *)malloc(MAX(w,h) * sizeof(int)); int divsum = (div + 1) >> 1; divsum *= divsum; int *dv = (int *)malloc(256 * divsum * sizeof(int)); for (i = 0; i < 256 * divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int)); 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 + (MIN(wm, MAX(i, 0)))]; sir = stack[i + radius]; sir[0] = (p & 0xff0000) >> 16; sir[1] = (p & 0x00ff00) >> 8; sir[2] = (p & 0x0000ff); rbs = r1 - 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] = 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 = MAX(0, yp) + x; sir = stack[i + radius]; sir[0] = r[yi]; sir[1] = g[yi]; sir[2] = b[yi]; rbs = r1 - 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] = 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; } } free(r); free(g); free(b); free(vmin); free(dv); free(stack); return(pix); }
最后来一张屌丝做demo专业效果图:
评论
11 楼
我说123木头人雪雪
2018-06-05
10 楼
ysc123shift
2017-11-10
没有源码。
9 楼
yihuangol
2016-12-01
hahhaha
8 楼
楼主说我长得帅
2016-05-07
不能下在源码玩毛线
7 楼
qq_24128067
2016-05-05
我去坑我啊! 源码下载不了! 我还去注册了的!
6 楼
xcj_199058
2016-03-29
给个源码看看
5 楼
i-teye
2016-02-17
怎么还权限不够,下载不了?
4 楼
zhaotong1991
2015-11-27
3 楼
天照811
2015-10-26
我也想看源码
2 楼
gqdy365
2015-10-09
zhaokaixin 写道
怎么不给个源码下载的地方呢
全部代码见http://gqdy365.iteye.com/admin/blogs/2199256;
1 楼
zhaokaixin
2015-09-02
怎么不给个源码下载的地方呢
发表评论
-
Android仿微博菜单弹出效果
2015-04-03 18:46 6611先上效果图,这个截图不是很流畅,大家可以下载apk试一下。 ... -
android AnimatorSet AnimationSet 的区别
2015-03-20 15:57 9366Android动画分类: 一、Tweened Animatio ... -
Android ListView项收缩效果
2015-01-29 18:37 7306项目中看到IOS上LIstView在显示隐藏一部分时有一个收缩 ... -
Android AnimationDrawable动画实例
2015-01-23 17:39 52251、定义animation_list.xml <?x ...
相关推荐
首先,高斯模糊是一种常见的图像处理技术,它通过对图像应用特定的权重函数(高斯函数)来模糊图像,使得边缘逐渐过渡,产生平滑的模糊效果。在Android中,我们通常使用Bitmap对象进行图像处理,包括高斯模糊。 `...
在Android开发中,实现高斯模糊(Gaussian Blur)是一种常见的图像处理技术,它能够为UI元素添加一种柔和且专业的视觉效果。实时模糊则是在用户交互过程中动态地应用这种效果,提升用户体验。本文将深入探讨如何在...
在Android平台上,截屏和对截图进行模糊处理是常见的需求,尤其在开发用户界面或调试应用时。本文将深入探讨如何实现这两个功能,并基于提供的"TestPrintScreenAndBlur"压缩包文件来解释其中的FastBlur算法。 首先...
2. 模糊处理:对截取的背景图片应用高斯模糊算法,这可能涉及到Bitmap的拷贝和转换。 3. 显示结果:将模糊后的背景设置到PopupWindow上,通常会创建一个新的ViewGroup,将模糊后的背景作为背景图片,然后将实际的...
在Android开发中,"高斯模糊"是一种常见的视觉效果,常用于实现背景的淡化或者突出显示某个区域。这种效果在很多应用中都有所体现,比如...无论哪种方式,理解高斯模糊的基本原理和Android图像处理机制都是非常重要的。
通常会先截图(截取需要模糊的背景区域)然后对截图进行模糊处理,最后将模糊后的图像绘制到一个新的视图上。由于要实现“实时”效果,所以这整个过程需要在运行时动态完成,且可能涉及到性能优化。 为了截图,可以...
在Android开发中,高斯模糊是一种常见的视觉效果,用于创建图像的柔和或半透明外观,常用于背景、对话框或者一些UI元素上,以增加设计的层次感和专业性。本"高斯模糊demo"旨在展示如何在Android应用中实现这一效果。...
在Android平台上,实现模糊虚化图片截屏涉及到多个技术层面,包括屏幕截图、图像处理以及模糊效果的实现。本文将详细讲解如何在Android应用中创建一个具有模糊效果的截图功能。 1. **屏幕截图** - Android提供了...
高斯模糊是一种图像处理技术,通过对图像中的每个像素应用高斯函数进行加权平均,使得图像变得模糊,但同时保留了边缘的清晰度。在Android中,我们可以使用 Renderscript 或者自定义视图(View)的方式实现这一效果...
Android 高斯模糊 + 截屏(注意android版本)
2. 模糊化:将获取的图片进行模糊化处理,使用高斯模糊算法对图片进行处理。 3. 设置背景:将模糊化后的图片设置为 Dialog 的背景图片。 代码实现: 首先,定义一个 FastBlurUtility 工具类,用于实现截屏和模糊化...
1. **Bitmap操作**:首先获取当前屏幕截图,然后对Bitmap进行高斯模糊处理。这可以通过创建自定义模糊算法或者使用第三方库如`android-gpuimage`来实现。GPU处理能提供更快的性能,尤其是在大尺寸图像上。 2. **...
开发者可以编写RenderScript脚本来实现模糊算法,比如高斯模糊,然后将其应用于Bitmap上,从而达到模糊效果。 4. GPUImage库:GPUImage是一个跨平台的图像处理库,它利用GPU进行图像处理,效率较高。在Android中,...
3. **应用模糊效果**:对Bitmap应用模糊处理,设置合适的模糊半径。 4. **将模糊后的Bitmap设置为背景**:将模糊处理后的Bitmap设置为你要添加模糊背景的View的背景。 需要注意的是,模糊处理可能会消耗较多的计算...
基本步骤包括获取屏幕截图,对截图进行高斯模糊处理,然后将模糊后的图片作为Dialog的背景。高斯模糊算法可以通过卷积矩阵实现,对每个像素进行计算,使其与周围像素混合,从而产生模糊效果。 2. **自定义Dialog**...
同时,为了保持图片的清晰度,可能还需要采用高斯模糊或者其他图像处理技术来优化边缘效果。 此外,项目的代码结构和设计模式也是值得学习的部分。良好的代码组织可以提高代码的可读性和可维护性。例如,开发者可能...
`BlurViewDemo`是一个示例项目,它演示了如何在Android应用中实现高斯模糊效果,尤其适用于需要对某个视图进行背景模糊处理的情况。这个项目主要使用Java语言编写,虽然现代Android开发更倾向于使用Kotlin,但Java...