Android 如何从onImageAvailable正确接收相机图像?
我正在尝试实现从一个android设备到另一个设备的视频流。为了做到这一点,我想从相机获取帧,通过插座发送,并在另一部手机的ImageView上显示。问题是我必须使用特定格式的ImageReader-YUV_420_888。当我尝试根据这个图像的字节创建位图时,我只能得到ALPHA_8(其他格式导致异常,称缓冲区不够大,无法容纳像素),它是黑白+错误定向的。我想知道是否有一种方法可以直接获得正确的版本,或者以某种方式转换它,这样我就可以制作一个合适的位图来显示在ImageView上。下面是一些代码:Android 如何从onImageAvailable正确接收相机图像?,android,live-streaming,android-camera2,Android,Live Streaming,Android Camera2,我正在尝试实现从一个android设备到另一个设备的视频流。为了做到这一点,我想从相机获取帧,通过插座发送,并在另一部手机的ImageView上显示。问题是我必须使用特定格式的ImageReader-YUV_420_888。当我尝试根据这个图像的字节创建位图时,我只能得到ALPHA_8(其他格式导致异常,称缓冲区不够大,无法容纳像素),它是黑白+错误定向的。我想知道是否有一种方法可以直接获得正确的版本,或者以某种方式转换它,这样我就可以制作一个合适的位图来显示在ImageView上。下面是一些代
public class MainActivity extends AppCompatActivity
{
private ImageReader mImageReader;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.imageView = (ImageView) findViewById(R.id.image);
this.handler = new Handler(){
@Override
public void handleMessage(Message msg)
{
if(msg.what == Worker.PROCESSED_IMAGE)
{
imageView.setImageBitmap((Bitmap) msg.obj);
}
}
};
}
private void openCamera()
{
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try
{
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.YUV_420_888, 50);
mImageReader.setOnImageAvailableListener(new Worker(this, this.handler, mPreviewSize.getWidth(), mPreviewSize.getHeight()), new Handler());
manager.openCamera(cameraId, mStateCallback, null);
}
catch(CameraAccessException e)
{
e.printStackTrace();
}
}
}
public class Worker implements ImageReader.OnImageAvailableListener
{
@Override
public void onImageAvailable(ImageReader imageReader)
{
Image image = imageReader.acquireLatestImage();
Image.Plane plane = image.getPlanes()[0];
ByteBuffer buffer = plane.getBuffer();
Bitmap bm = Bitmap.createBitmap(width, heigth, Bitmap.Config.ALPHA_8);
bm.copyPixelsFromBuffer(buffer);
image.close();
handler.obtainMessage(PROCESSED_IMAGE, bm).sendToTarget();
}
几乎正确,请尝试使用以下代码:
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
// Log.d(TAG, String.format(Locale.getDefault(), "image w = %d; h = %d", image.getWidth(), image.getHeight()));
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
buffer.rewind();
byte[] data = new byte[buffer.capacity()];
buffer.get(data);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//use your bitmap
} catch (Exception e) {
e.printStackTrace();
}
if (image != null) {
image.close();
}
}
此代码中的位图大小不正确。它没有填满屏幕。@Donato“它没有填满屏幕”-这与当前的问题/答案不匹配。可能您将大小设置错误,或者这只是UI问题。对于YUV_420_888,您需要图像的所有三个平面