我正在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()才能更新緩衝區。 –