我正在KitKat(4.4)中开发一个应用程序,并且最近在我的设备(5.1)上闪动了棒棒糖。我的RenderScript代码似乎已经“破损”了。我的意思是它编译得很好,但是当我启动应用程序时,它并没有做它应该做的事情。我用它来并行执行边缘检测,但它没有做任何事情。以前在KitKat上我可以看到边缘。现在它呈现相机看到的东西,没有效果,没有边缘检测。RenderScript停止在Android Lollilop中工作
这里是我的应用程序清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="foo.bar"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /-->
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".LiveCameraActivity"
android:screenOrientation="sensorLandscape" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这里是我的应用程序gradle这个build.gradle
文件:
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion '19.1.0'
defaultConfig {
applicationId "foo.bar"
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
renderscriptTargetApi 19
renderscriptSupportModeEnabled true //not applicable for rs targetapi 21+
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
或多或少这是我打电话给我的renderScript代码:
我将所有我的renderscript(.rs)文件放在main
下的rs
文件夹下。
而且在Java中:
bmp = mTextureView.getBitmap();
bmpCopy = bmp.copy(bmp.getConfig(),true); //create a copy of the original
bitmapProcessor.processBmpEdgeDetect(bmp, bmpCopy); //I think this is where it breaks
mImageView.setImageBitmap(bmpCopy); // render result
现在bitmapProcessor.processBmpEdgeDetect()
有这样的:
renderScriptEdgeDetectWrapper = new RenderScriptEdgeDetectWrapper(ctx);
renderScriptAvgOperWrapper.setInAllocation(bmp);
renderScriptAvgOperWrapper.setOutAllocation(bmpCopy);
renderScriptAvgOperWrapper.setScriptWidth(bmp.getWidth()-1);
renderScriptAvgOperWrapper.setScriptHeight(bmp.getHeight()-1);
renderScriptAvgOperWrapper.forEach_root();
而且我renderScriptAvgOperWrapper
基本上是这样的:
public class RenderScriptEdgeDetectWrapper {
private Allocation inAllocation;
private Allocation outAllocation;
private RenderScript rs;
private ScriptC_edgedetect edgeDetectScript;
private Context ctx;
public RenderScriptEdgeDetectWrapper(Context context){
ctx = context;
rs = RenderScript.create(ctx);
edgeDetectScript = new ScriptC_edgedetect(rs, ctx.getResources(), R.raw.edgedetect);
};
public void setInAllocation(Bitmap bmp){
inAllocation = Allocation.createFromBitmap(rs,bmp);
edgeDetectScript.set_inPixels(inAllocation);
};
public void setOutAllocation(Bitmap bmp){
outAllocation = Allocation.createFromBitmap(rs,bmp);
};
public void setScriptWidth(int scriptWidth) {
edgeDetectScript.set_width(scriptWidth);
}
public void setScriptHeight(int scriptHeight) {
edgeDetectScript.set_height(scriptHeight);
}
public void forEach_root(){
edgeDetectScript.forEach_root(inAllocation,outAllocation);
}
}
这只是一个简单的包装。
最后我的renderScript edgedetect.rs
文件是这样的:
#pragma version(1)
#pragma rs java_package_name(foo.bar)
rs_allocation inPixels;
int height;
int width;
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
float3 pixel = convert_float4(in[0]).rgb;
if(x==0 || x==width || y==0 || y==height){
pixel.r = 0;
pixel.g = 191;
pixel.b = 255;
}else{ //do image processing here
float3 pixelNH = convert_float4(rsGetElementAt_uchar4(inPixels, x+1, y)).rgb;
float3 pixelNV = convert_float4(rsGetElementAt_uchar4(inPixels, x, y+1)).rgb;
int grayAvg = (pixel.r + pixel.g + pixel.b)/3;
int grayAvgNH = (pixelNH.r + pixelNH.g + pixelNH.b)/3;
int grayAvgNV = (pixelNV.r + pixelNV.g + pixelNV.b)/3;
int edgeOperatorValue = 2*grayAvg - grayAvgNH - grayAvgNV;
if(edgeOperatorValue < 0){
edgeOperatorValue = -1 * edgeOperatorValue;
};
pixel.r = edgeOperatorValue;
pixel.g = edgeOperatorValue;
pixel.b = edgeOperatorValue;
};
out->xyz = convert_uchar3(pixel);
}
现在我不明白为什么这个代码在奇巧工作得很好,但在棒棒糖完全失败。如果你能指导什么是错的,那会很好。谢谢。
为什么在kitkat中工作?... –
如果发生零复制(即共享后备缓冲区),它可以工作。在那种情况下,copyTo()将不会执行任何操作。如果它不是零拷贝(即USAGE_SHARED),则必须copyTo()才能更新缓冲区。 –