如何从onImageAvailable正确接收相机图像?

时间:2016-08-01 14:05:49

标签: 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();

}

1 个答案:

答案 0 :(得分:2)

几乎正确,请尝试使用此代码:

@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();
    }
}