Android的毛玻璃模糊效果,我使用OpenCV来搞

作者:JerryloveEmily

地址:http://www.jianshu.com/p/d0d7809007a1

声明:本文是JerryloveEmily原创,已获其授权发布,未经原作者允许请勿转载

开始学习OpenCV,毛玻璃模糊效果目前网上流行的有三种办法:

1、使用java来编写一长串的像素处理办法算法来改变bitmap(性能教差,而且一堆算法代码,难理解,不优雅)

2、使用C语言的方式同样使用和java一样的算法来实现(性能好,同样一堆算法代码难理解,也不优雅)

3、使用RenderScript这个有Api版本的限制。

现在我们可以利用OpenCV框架中滤波算法来实现图片的模糊虚化。

准备工作

先到OpenCV官网, 下载Android平台的sdk包: http://www.opencv.org

解压后: sdk目录里是openCV的一些动态库,cmake构建文件,以及java的一些api。

新建一个支持NDK的工程:

配置集成OpenCV库到工程:

我这里只编译支持了armeabi,cpu架构的平台,需要在app,module的build.gradle中做一些修改:

对了这里我使用AS自带的cmake工具来构建NDK库的链接和编译的支持,所以不需要再写Android.mk的配置文件,这里配置下CMakeLists.txt就可以,更加简单:

# For more information about using CMake with Android Studio, read the

# documentation: https: # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # 添加我们自己要编译的so库,以及源码文件 add_library( image_process SHARED src/main/cpp/image_process.cpp ) # 增加opencv库 add_library( opencv_java3 SHARED IMPORTED ) # 编译的平台是armeabiif(${ANDROID_ABI} STREQUAL "armeabi")# 设置动态库文件的路径属性set_target_properties( opencv_java3 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/armeabi/libopencv_java3.so )endif(${ANDROID_ABI} STREQUAL "armeabi")# opencv库的头文件路径设置,在此是opencv-sdk的路径,当然你也可以把include目录拷贝到工程中include_directories( D:/opencv-3.2.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/include )find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log )# 需要链接的库target_link_libraries( # Specifies the target library. image_process opencv_java3 # Links the target library to the log library # included in the NDK. ${log-lib} )

上面的添加依赖库,和自己要编译的so库的写法都是差不多的,就是这些套路。(自古深情留不住,总是套路得人心) 同时把sdk中libopencv_java3.so文件拷贝到对应的工程目录下我这里是jniLibs为了方便不然还得配置gradle修改source目录的映射路径:

编写java层的对外开发调用api

public class ImageProcessUtils {

public static Bitmap blur(Bitmap srcBitmap){ int width = srcBitmap.getWidth(); int height = srcBitmap.getHeight(); int[] pixels = new int[width * height]; srcBitmap.getPixels(pixels, 0, width, 0, 0, width, height); blurImage(pixels, width, height); Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); newBitmap.setPixels(pixels, 0, width, 0, 0, width, height); return newBitmap; } public static native void blurImage(int[] pixels, int w, int h); static { System.loadLibrary("image_process"); System.loadLibrary("opencv_java3"); } }

接下来是在NDK中使用opencv来实现图片的毛玻璃化

#include <jni.h>

#include <android/log.h> #include <opencv2/opencv.hpp> // 引入opencv库头文件 #include <opencv2/highgui/highgui.hpp> // 引入opencv图形界面,暂时没用到 // 定义了log日志宏函数,方便打印日志在logcat中查看调试 #define TAG "Jerry-NDK-Image-Pro" #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG, __VA_ARGS__) using namespace cv; extern "C" JNIEXPORT void JNICALL Java_com_jerry_jerryopencvdemo_imageprocess_ImageProcessUtils_blurImage( JNIEnv *env, jclass jcls, jintArray jarr_pixels, jint j_width, jint j_height) { // 获取java中传入的像素数组值,jintArray转化成jint指针数组 jint *c_pixels = env->GetIntArrayElements(jarr_pixels, JNI_FALSE); if(c_pixels == NULL){ return; } LOGE("图片宽度:%d, 高度:%d", j_width, j_height); // 把c的图片数据转化成opencv的图片数据 // 使用Mat创建图片 Mat mat_image_src(j_height, j_width, CV_8UC4, (unsigned char*) c_pixels); // 选择和截取一段行范围的图片 Mat temp = mat_image_src.rowRange(j_height / 3, 2 * j_height / 3); // 方框滤波 // boxFilter(temp, temp, -1, Size(85, 85)); // 均值滤波 blur(temp, temp, Size(85, 85)); // 使用高斯模糊滤波 // GaussianBlur(temp, temp, Size(45, 13), 0, 0); // 将opencv图片转化成c图片数据,RGBA转化成灰度图4通道颜色数据 cvtColor(temp, temp, CV_RGBA2GRAY, 4); // 更新java图片数组和释放c++中图片数组的值 env->ReleaseIntArrayElements(jarr_pixels, c_pixels, JNI_FALSE); }

原图:

毛玻璃后效果图:

简单的利用了滤波算法函数处理,来达到毛玻璃的效果,当然opencv的强大远远不限于此。关于opencv进一步的学习使用还会继续记录在博客中。

原文发布于微信公众号 - Android先生(cyg_24kshign)

原文发表时间:2017-10-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

数据库静默安装总结(r3笔记第58天)

在学习数据库的时候,不知道dbca的命令用了多少遍,但是越是安装也是觉得自己会的越少,因为图形界面的清晰直白反而不知道哪些准备工作是需要特别准备的,如果在远程支...

33480
来自专栏张善友的专栏

How to Select an Object-Relational Mapping Tool for .NET

The single, most important trap to watch out for when choosing an object-relatio...

18080
来自专栏逍遥剑客的游戏开发

做了Nebula3的应用程序向导

12930
来自专栏Android先生

【漫画技术】Android跨进程通信

Tips:4个环节,共计约9小时的精心打磨完成上线,同时也非常感谢参与审稿的同学。

12120
来自专栏乐沙弥的世界

Failed to upgrade Oracle Cluster Registry configuration(root.sh)

    最近在给客户基于Suse 11 sp3安装Oracle 10g RAC,在安装完clusterware执行/u01/app/crs/root.sh时收...

10210
来自专栏Golang语言社区

也许你并不需要 REST

Nearly 10 years ago, Leonard Richardson and Sam Ruby publishedRESTful Web Servic...

8620
来自专栏小二的折腾日记

day5(面向对象2)

java.Awt: Abstract Window ToolKit (抽象窗口 工具包),需要调用本地系统方法实现功能。属 重量级控件。 javax.Swing...

7320
来自专栏bboysoul

制作免杀windows木马(Winpayloads )

下载 git clone https://github.com/nccgroup/Winpayloads.git cd Winpayloads 安装 c...

11510
来自专栏移动开发面面观

JNI处理图片——黑白滤镜

20420
来自专栏Netkiller

怎样制作RPM包

怎样制作RPM包 摘要 我在网上找RPM包的制作例子几乎都是C源码编译安装然后生成RPM包, 而我的程序不是C写的很多时候是脚本语言如Python, PHP 甚...

76760

扫码关注云+社区

领取腾讯云代金券