RenderScript使用教程(二)
NDK中使用RenderScript
编写一个rs脚本文件
实现灰度转换的代码
#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.hellocomputendk)
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
void root(const uchar4 *v_in, uchar4 *v_out) {
float4 f4 = rsUnpackColor8888(*v_in);
float3 mono = dot(f4.rgb, gMonoMult);
*v_out = rsPackColorTo8888(mono);
}
编写NDK调用代码
#include <jni.h>
#include <android/log.h>
#include <android/bitmap.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <RenderScript.h>
#include "ScriptC_mono.h"
#include "demo_ndk_rs_wps_cn_rsndkdemo_MainActivity.h"
#define LOG_TAG "HelloComputeNDK"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
using namespace android::RSC;
extern "C" JNIEXPORT void JNICALL
Java_demo_ndk_rs_wps_cn_rsndkdemo_MainActivity_nativeMono(JNIEnv * env, jclass, jstring pathObj, jint X, jint Y, jobject jbitmapIn, jobject jbitmapOut) {
void* inputPtr = nullptr;
void* outputPtr = nullptr;
AndroidBitmap_lockPixels(env, jbitmapIn, &inputPtr);
AndroidBitmap_lockPixels(env, jbitmapOut, &outputPtr);
const char * path = env->GetStringUTFChars(pathObj, nullptr);
sp<RS> rs = new RS();
rs->init(path);
env->ReleaseStringUTFChars(pathObj, path);
sp<const Element> e = Element::RGBA_8888(rs);
sp<const Type> t = Type::create(rs, e, X, Y, 0);
sp<Allocation> inputAlloc = Allocation::createTyped(rs, t, RS_ALLOCATION_MIPMAP_NONE,
RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
inputPtr);
sp<Allocation> outputAlloc = Allocation::createTyped(rs, t, RS_ALLOCATION_MIPMAP_NONE,
RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_SCRIPT,
outputPtr);
inputAlloc->copy2DRangeFrom(0, 0, X, Y, inputPtr);
ScriptC_mono* sc = new ScriptC_mono(rs);
sc->forEach_root(inputAlloc, outputAlloc);
outputAlloc->copy2DRangeTo(0, 0, X, Y, outputPtr);
AndroidBitmap_unlockPixels(env, jbitmapIn);
AndroidBitmap_unlockPixels(env, jbitmapOut);
}
编写编译mk文件
android.mk文件如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := rstest-compute
LOCAL_SRC_FILES:=main.cpp mono.rs
LOCAL_C_INCLUDES += D:/Android/android-ndk-r14b-windows-x86_64/android-ndk-r14b/toolchains/renderscript/prebuilt/windows-x86_64/platform/rs/cpp \
D:/Android/android-ndk-r14b-windows-x86_64/android-ndk-r14b/toolchains/renderscript/prebuilt/windows-x86_64/platform/rs
LOCAL_CFLAGS := -std=c++11
LOCAL_LDFLAGS := -Wl,-Bsymbolic
#LOCAL_RENDERSCRIPT_COMPATIBILITY := true
LOCAL_SHARED_LIBRARIES := RSSupport blasV8 RSSupportIO
LOCAL_STATIC_LIBRARIES := RScpp_static
LOCAL_LDLIBS := -llog -ljnigraphics -lz -ldl
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/renderscript)
这里注意LOCAL_C_INCLUDES 请写你本地对应NDK有关rs头文件的目录。
application.mk文件如下:
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
APP_STL := stlport_static
编译代码
这里需要注意必须使用linux系统或者babun去编译文件,因为在window命令行下有NDK有一个bug,具体请查看编译以及注意事项请查看该链接。
Java调用测试
private Bitmap mBitmapIn;
private Bitmap mBitmapOut;
private ImageView iv_show;
private ImageView iv_input;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("rstest-compute");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBitmapIn = ((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap();
mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(), mBitmapIn.getConfig());
nativeMono(this.getCacheDir().toString(),
mBitmapIn.getWidth(), mBitmapIn.getHeight(),
mBitmapIn, mBitmapOut);
iv_show = (ImageView) findViewById(R.id.iv_show);
iv_input = (ImageView) findViewById(R.id.iv_input);
iv_input.setImageBitmap(mBitmapIn);
iv_show.setImageBitmap(mBitmapOut);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
native void nativeMono(String cacheDir, int X, int Y, Bitmap in, Bitmap out);