前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android的毛玻璃模糊效果,我使用OpenCV来搞

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

作者头像
用户2802329
发布2018-08-07 15:19:41
1.2K0
发布2018-08-07 15:19:41
举报
文章被收录于专栏:Android先生Android先生
作者: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进一步的学习使用还会继续记录在博客中。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android先生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 新建一个支持NDK的工程:
  • 配置集成OpenCV库到工程:
  • 原图:
  • 毛玻璃后效果图:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档