我是Android的初学者,我必须创建一个应用程序,使用Camera2实时绘制以RGB格式处理的相机图像。 我已经创建了一个活动,我根据谷歌示例为Camera2绘制数据和片段。好吧,关于相机的部分工作,但我有ImageReader处理帧的问题。在openCamera中,我为Image Reader打开了一个监听器,我试图创建一个后台线程来获取帧数据。
private void openCamera(int width, int height) {
// another part of code
ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Thread mythread = new Thread(new Runnable() {
@Override
public void run(){
readImage = mImageReader.acquireLatestImage();
if (readImage == null){
Log.e(TAG, "ERROR");
}
float[] val = caricadato(readImage);
try {
Thread.sleep(100); //600
} catch (InterruptedException e) {
//manage error...
}
}
});
mythread.start();}
};
mImageReader = ImageReader.newInstance(176, 144,
35, 1);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
//....continue
}
“carica dato”方法提取绿色通道并使其成为平均值(要绘制的数据)。
private float[] caricadato(Image image){
Log.i(TAG, "The onImageAvailable thread id: " + Thread.currentThread().getId());
float[] v = yuv2rgb(image);
float media = valore_medio(v);
dati_realtime[count]= media;
Log.i(TAG,"dato media"+ media);
Log.i(TAG,"dato real time "+ dati_realtime[count]);
Log.i(TAG,"VALORE CONTATORE "+count);
count++;
image.close();
return dati_realtime;
}
private float[] yuv2rgb(Image image){
ByteBuffer buffer0 = image.getPlanes()[0].getBuffer();
byte[] Y1 = new byte[buffer0.remaining()];
buffer0.get(Y1);
ByteBuffer buffer1 = image.getPlanes()[1].getBuffer();
byte[] U1 = new byte[buffer1.remaining()];
buffer1.get(U1);
ByteBuffer buffer2 = image.getPlanes()[2].getBuffer();
byte[] V1 = new byte[buffer2.remaining()];
buffer2.get(V1);
int Width = image.getWidth();
int Height = image.getHeight();
float[]verdi = new float[image.getHeight()*image.getWidth()];
int contatore = 0;
for(int i = 0; i<Height-1; i++){
for (int j = 0; j<Width; j++){
int Y = Y1[i*Width+j]&0xFF;
int U = U1[(i/2)*(Width/2)+j/2]&0xFF;
int V = V1[(i/2)*(Width/2)+j/2]&0xFF;
U = U-128;
V = V-128;
float R,G,B;
R = (float)(Y + 1.402 * V);
G = (float)(Y - 0.34414 * U - 0.71414 * V);
B = (float) (Y + 1.772 * U);
verdi[contatore]= (byte)G;
contatore++;
}
}
return verdi;
}
启动和恢复时的错误通常是:
E/AndroidRuntime: FATAL EXCEPTION: Thread-5 Process: com.example.francesca.beatandgo, PID: 22610
java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more.
at android.media.ImageReader.acquireNextImage(ImageReader.java:398)
at android.media.ImageReader.acquireLatestImage(ImageReader.java:283)
at com.example.francesca.beatandgo.camera.Camera2VideoFragment$3$1.run(Camera2VideoFragment.java:506)
at java.lang.Thread.run(Thread.java:776)
Camera2VideoFragment.java:506在openCamera中为readImage = mImageReader.acquireLatestImage();
。
如何解决此问题?如何将数据传递给mainThread进入Activity?