如何使用Camera2 AndroidImageReader获取预览图像无预览图

问题描述

问题有点奇怪。 (我看到黑色的预览纹理)我带有自己的解决方案,不显示预览,而是将预览缓冲区刷新到Byte [](但是将显示预览,但是显示在opengl纹理上(本机)) 无论如何,使camera2 api正常工作后,我实际上从ImageReader获取图像时遇到问题。

首先,我想澄清一下:为了不显示任何预览(未处理),我仅将ImageReaders表面传递给CaptureRequestBuilder。

 List<Surface> surfaces =new ArrayList<>();

        Surface frameCaptureSurface = mImageReader.getSurface();
        surfaces.add(frameCaptureSurface);
        mCaptureRequestbuilder.addTarget(frameCaptureSurface);

OnImageAvailable()触发,但是数据似乎已损坏,如果我将其保存到文件中,irfanview会告诉我标头已损坏等。不知何故,字节已填充,但在此肯定有问题。

这是我目前正在做的代码

        Activity shared_activity;
    boolean initialized;



    CameraDevice mCameraDevice;
    Size mSize;

     byte[] mFrame;

    ImageReader         mImageReader;
    HandlerThread       mCamSessionThread;
    Handler             mCamSessionHandler;

     CaptureRequest.Builder mCaptureRequestbuilder;
    CaptureRequest mCaptureRequest;
    CameraCaptureSession mCameraCaptureSession;

    


    public PCPHOnesHAREView(Context context,Activity sa,ClipboardManager clp)
    {
        super(context);
        shared_activity = sa;
        clipBoard = clp;
        initialized = false;
 
        init(false,0);


        setKeepScreenOn(true);
    }

    boolean invoke_cam_upload = false;

    final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader imageReader) {
        LOGE("New frame avil");
if (update_cam_tex) return;
if (invoke_cam_upload) return;
            invoke_cam_upload = true;
            LOGE("copy new frame to global buffer");


            Image image = imageReader.acquireNextimage();

//Now i cant remember exactly where it throws an error (first below or second one)
//E/ion: ioctl c0044901 Failed with code -1: Invalid argument
            Image.Plane[] planes = image.getPlanes();
            ByteBuffer buffer = planes[0].getBuffer();

            buffer.rewind();
            mFrame  = new byte[buffer.capacity()];
            buffer.get(mFrame);
        
            image.close();

            update_cam_tex = true;
            invoke_cam_upload = false;
        }
    };

final public    CameraCaptureSession.StateCallback mCaptureStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured( CameraCaptureSession cameraCaptureSession) {
            try {


                mCaptureRequest= mCaptureRequestbuilder.build();

                mCameraCaptureSession = cameraCaptureSession;
                mCameraCaptureSession.setRepeatingRequest(mCaptureRequest,null,mCamSessionHandler);

                CameraOpenedAndPreviewAvil(mSize.getWidth(),mSize.getHeight());
                if (mCameraDevice == null) LOGE("CAM NULL");
                LOGE("CAP SESSION IS CONfigURED");
            } catch (Throwable t) {
                LOGE("CAM SESSION ERROR");
            }
        }

        @Override
        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
            LOGE("CONfig Failed");
        }
    };

    final public CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onopened( CameraDevice cameraDevice) {
            mCameraDevice = cameraDevice;

            createCameraPreviewSession();
            LOGE("CREATE PREV SESSION");
        }
        @Override
        public void ondisconnected( CameraDevice cameraDevice) {
            mCameraDevice = null;
            LOGE("CAM disC");
        }

        @Override
        public void onError( CameraDevice cameraDevice,int i) {
            mCameraDevice = null;
            LOGE("CAM ERROR");
        }
    };

    private void createCameraPreviewSession() {



        try {
            LOGE("CONfigURING BUILDER");
            mCaptureRequestbuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mCaptureRequestbuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

            List<Surface> surfaces =new ArrayList<>();

            Surface frameCaptureSurface = mImageReader.getSurface();
            surfaces.add(frameCaptureSurface);
            mCaptureRequestbuilder.addTarget(frameCaptureSurface);

            mCameraDevice.createCaptureSession(surfaces,mCaptureStateCallback,mCamSessionHandler);
        } catch (Throwable t) {
            LOGE("CREATE PREV SESSION ERROR "+t.getMessage());
        }



    }


   public void openCameraT() {
//cam_tex.addCallback(this);

        CameraManager cameraManager = (CameraManager) shared_activity.getSystemService(Context.CAMERA_SERVICE);
        try {
            String cameraId = cameraManager.getCameraIdList()[0];
            Cameracharacteristics characteristics
                    = cameraManager.getCameracharacteristics(cameraId);
            StreamConfigurationMap map = characteristics.get(
                    Cameracharacteristics.SCALER_STREAM_CONfigURATION_MAP);

            mSize = map.getoutputSizes(SurfaceTexture.class)[map.getoutputSizes(SurfaceTexture.class).length-2];



            mCamSessionThread = new HandlerThread("Camera2");
            mCamSessionThread.start();
            mCamSessionHandler = new Handler(mCamSessionThread.getLooper());

            mImageReader = ImageReader.newInstance(mSize.getWidth(),mSize.getHeight(),ImageFormat.YUV_420_888,1);
            mImageReader.setonImageAvailableListener(mOnImageAvailableListener,mCamSessionHandler);

            LOGE("opening CAMERA");
            cameraManager.openCamera(cameraId,mStateCallback,mCamSessionHandler);
        } catch (Throwable t) {

            LOGE(t.getMessage());
        }

    }

    private void closeCamera() {
        try {
            if (null != mCameraDevice)
                mCameraDevice.close();
        } catch (Throwable t) {

        }
    }





----
On gl thread
   public void onDrawFrame(GL10 gl) {
        if (!initialized)
        {
            init(scrw,scrh);
            initialized = true;
        } else
        {

if (update_cam_tex)
{
    LOGE("update_cam_tex");

    throwing_cam_buff = true;

    SetCamTex(mFrame); //native call to pass imageReader byte buffer as bytes[] convert it to rgb and save as texture
    update_cam_tex = false;
    throwing_cam_buff = false;
}
            step();
        }
        }

这是logcat的输出

     AGAIN INITIALIZE
 SW 2255 SH: 1080
QR CODE
Scan
opening CAMERA
CONfigURING BUILDER
CREATE PREV SESSION
CAM C++ DATA READY: w: 208 h: 144
CAP SESSION IS CONfigURED
New frame avil
copy new frame to global buffer
E/ion: ioctl c0044901 Failed with code -1: Invalid argument
update_cam_tex
SETTING CAM TEX,len = 6
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA !
New frame avil
copy new frame to global buffer
update_cam_tex
SETTING CAM TEX
PDATA #

SETTING CAM TEX

PDATA#//这显示了mFrame [400]中的字符

无论如何,尝试访问ImageReader缓冲区时出现奇怪的错误 E / ion:ioctl c0044901失败,代码为-1:参数无效

我知道我应该使用两个纹理上载mFrame的功能,但是现在我需要正确处理ImageReader图像转换为未签名的字符*

欢呼

Result

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)