Android毛玻璃效果实现
来源:互联网 发布:管家婆数据库安装教程 编辑:程序博客网 时间:2024/03/29 08:34
最近在研究Android的毛玻璃效果,图片加上毛玻璃的效果很不错,lipeil的博文给出了JAVA和C实现的方法,由于JAVA方法实现性能较低,本文将其中的C实现的方法修改为JNI可调用的方法,可以以较高的性能实现图片的毛玻璃效果处理。
#include <jni.h>#include <stdio.h>#include <malloc.h>#define MAX(a,b)((a>b)?(a):(b))#define MIN(a,b)((a<b)?(a):(b))#define ABS(x) ((x)>=0 ? (x):(-(x)))JNIEXPORT jintArray JNICALL Java_com_clazz_BulrManager_StackBlur(JNIEnv *env, jobject obj, jintArray array1, jint w, jint h, jint radius){const jsize length = env->GetArrayLength(array1);jintArray newArray = env->NewIntArray(length);jint *pix;pix = env->GetIntArrayElements(array1, NULL);jint *narr = env->GetIntArrayElements(newArray, NULL); jint wm = w - 1; jint hm = h - 1; jint wh = w * h; jint div = radius + radius + 1; jint *r = (jint *)malloc(wh * sizeof(jint)); jint *g = (jint *)malloc(wh * sizeof(jint)); jint *b = (jint *)malloc(wh * sizeof(jint)); jint rsum, gsum, bsum, x, y, i, p, yp, yi, yw; jint *vmin = (jint *)malloc(MAX(w,h) * sizeof(jint)); jint divsum = (div + 1) >> 1; divsum *= divsum; jint *dv = (jint *)malloc(256 * divsum * sizeof(jint)); for (i = 0; i < 256 * divsum; i++) { dv[i] = (i / divsum); } yw = yi = 0; jint(*stack)[3] = (jint(*)[3])malloc(div * 3 * sizeof(jint)); jint stackpointer; jint stackstart; jint *sir; jint rbs; jint r1 = radius + 1; jint routsum, goutsum, boutsum; jint 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); for(jint x = 0; x < length; x ++){ narr[x]=pix[x]; } env->ReleaseIntArrayElements(newArray, narr, NULL); env->ReleaseIntArrayElements(array1, pix, NULL); return newArray;}jint JNI_OnLoad(JavaVM *vm, void *reserved){void *venv;if(vm->GetEnv((void**)&venv, JNI_VERSION_1_4)!=JNI_OK){return -1;}return JNI_VERSION_1_4;}
JAVA层调用
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.image); Bitmap bitmap = mBitmap.copy(mBitmap.getConfig(), true);//做一份Bitmap拷贝,拷贝的图片是可以被修改的。int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] pix = new int[w*h];bitmap.getPixels(pix, 0, w, 0, 0, w, h);bitmap.setPixels(BulrManager.StackBlur(pix, w, h, 3), 0, w, 0, 0, w, h);//调用jni中的C方法处理图片,并修改图片的pixels值实现毛玻璃效果iv.setImageBitmap(bitmap);if(mBitmap!=null && !mBitmap.isRecycled()){ mBitmap.recycle();}
实现的效果图:
1 0
- Android毛玻璃效果实现
- Android实现毛玻璃效果
- Android毛玻璃效果实现
- android实现的毛玻璃效果
- android快速实现毛玻璃效果
- Android 毛玻璃效果的实现
- Android 毛玻璃效果实现(Glide)
- android快速实现毛玻璃效果
- Android毛玻璃效果简单实现
- Android快速实现毛玻璃效果
- Android Fresco实现图片毛玻璃效果
- Android快速毛玻璃虚化效果实现
- Android模糊处理简单实现毛玻璃效果
- android 毛玻璃模糊效果背景实现
- Android中毛玻璃效果的实现
- Android中实现iOS中的毛玻璃效果
- Android使用glide实现毛玻璃效果
- Android毛玻璃效果的实现(本文系转载一种快速毛玻璃虚化效果实现)
- Android Studio 启动问题
- 记录一个在线代码格式化网络
- git pull 命令指定路径
- Android分辨率详解
- Eclipse配色方案导入另外一台电脑
- Android毛玻璃效果实现
- ubuntu14.10下查看Django源文件的路径位置
- 《老罗的Android之旅》阅读笔记——应用程序与SurfaceFlinger服务的关系
- Android:单元测试Junit的配置
- 自绘控件的4种方法
- Nginx+session共享+memcached+cobar 前端负载均衡+数据库分布式处理(基础版本)
- 02-2
- 初窥设计模式之外观模式(Facade)
- Andorid优化系统启动速度之启用DEXPREOPT