我正在尝试使用Renderscript将YUV NV21图像转换为Android中的黑白图像。我是Renderscript的新手,在打电话时
mScript.forEach_root(inAllocation, outAllocation);
我收到以下错误:
android.support.v8.renderscript.RSRuntimeException: Dimension mismatch between parameters ain and aout!
at org.rwca.anthe.robocup15.ScriptC_imageProc.forEach_root(ScriptC_imageProc.java:87)
at org.rwca.anthe.robocup15.ScriptC_imageProc.forEach_root(ScriptC_imageProc.java:66)
at org.rwca.anthe.robocup15.MainActivity$imgProc.process(MainActivity.java:115)
at io.fotoapparat.FotoapparatBuilder$frameProcessor$2$1$1.invoke(FotoapparatBuilder.kt:137)
at io.fotoapparat.FotoapparatBuilder$frameProcessor$2$1$1.invoke(FotoapparatBuilder.kt:21)
at io.fotoapparat.preview.PreviewStream.dispatchFrame(PreviewStream.kt:107)
at io.fotoapparat.preview.PreviewStream.access$dispatchFrame(PreviewStream.kt:16)
at io.fotoapparat.preview.PreviewStream$dispatchFrameOnBackgroundThread$1.run(PreviewStream.kt:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
所以我做到了:
byte[] test = copyOfRange(nv21ByteArray, 0, size); //copyOfRange(...) is inAllocation
Log.i(TAG, String.valueOf(test.length));
Log.i(TAG, String.valueOf(bitmap.getByteCount())); //bitmap is outAllocation
我发现它们都等于1 228800。那么错误是什么意思?因为inAllocation和outAllocation应该是相同的大小吧?
这是我的Java代码:
package org.rwca.anthe.robocup15;
import android.graphics.Bitmap;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v8.renderscript.Type;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
import org.jetbrains.annotations.NotNull;
import io.fotoapparat.Fotoapparat;
import io.fotoapparat.error.CameraErrorListener;
import io.fotoapparat.exception.camera.CameraException;
import io.fotoapparat.parameter.ScaleType;
import io.fotoapparat.preview.Frame;
import io.fotoapparat.preview.FrameProcessor;
import io.fotoapparat.view.CameraView;
import static io.fotoapparat.log.LoggersKt.fileLogger;
import static io.fotoapparat.log.LoggersKt.logcat;
import static io.fotoapparat.log.LoggersKt.loggers;
import static io.fotoapparat.selector.LensPositionSelectorsKt.back;
import static java.util.Arrays.copyOfRange;
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private CameraView cameraView;
private ImageView imageView;
private Fotoapparat fotoapparat;
public byte[] nv21ByteArray;
public int size = 960 * 1280;
public int thresholdValue;
public Bitmap bitmap;
public RenderScript rs;
public Allocation inAllocation, outAllocation;
public ScriptC_imageProc mScript;
@NonNull
private Fotoapparat createFotoapparat() {
return Fotoapparat
.with(this)
.into(cameraView)
.previewScaleType(ScaleType.CenterCrop)
.lensPosition(back())
.frameProcessor(new imgProc())
.logger(loggers(
logcat(),
fileLogger(this)
))
.cameraErrorCallback(new CameraErrorListener() {
@Override
public void onError(CameraException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();;
}
})
.build();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cameraView = findViewById(R.id.cameraView);
imageView = findViewById(R.id.imageView);
fotoapparat = createFotoapparat();
bitmap = Bitmap.createBitmap(960, 1280, Bitmap.Config.ALPHA_8);
rs = RenderScript.create(this);
mScript = new ScriptC_imageProc(rs);
Type t = Type.createX(rs, Element.U8(rs), size);
inAllocation = Allocation.createTyped(rs, t);
outAllocation = Allocation.createFromBitmap(rs, bitmap);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStart() {
super.onStart();
fotoapparat.start();
}
@Override
protected void onStop() {
super.onStop();
fotoapparat.stop();
}
private class imgProc implements FrameProcessor {
@Override
public void process(@NotNull Frame frame) {
nv21ByteArray = frame.getImage();
inAllocation.copyFromUnchecked(copyOfRange(nv21ByteArray, 0, size));
mScript.set_thresholdValue(thresholdValue);
mScript.forEach_root(inAllocation, outAllocation);
outAllocation.copyTo(bitmap);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}
}
这是我的Renderscript文件:
#pragma version(1)
#pragma rs java_package_name(org.rwca.anthe.robocup15)
#include "rs_core.rsh"
#include "rs_time.rsh"
int thresholdValue;
uchar __attribute__((kernel)) root(uchar in, uint32_t x) {
}