Get bitmap without transformations from TextureView

4.1k views Asked by At

I am currently developing an application which use Camera2. I display the preview on a TextureView which is scaled and translated (I only need to display a part of the image). My problem is that I need to analyze the entire image.

What I have in my CameraDevice.StateCallback :

@Override
    public void onOpened(CameraDevice camera) {
        mCameraDevice = camera;

        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        Surface surface = new Surface(texture);

        try {
            mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        } catch (CameraAccessException e){
            e.printStackTrace();
        }

        try {
            mCameraDevice.createCaptureSession(Arrays.asList(surface), mPreviewStateCallback, null);
            mPreviewBuilder.addTarget(surfaceFull);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

and in my SurfaceTextureListener :

@Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                my_analyze(mTextureView.getBitmap());
            }
        });
        thread.start();
    }

And the bitmap is only what I see in the TextureView (which is logical) but I want the entire image.

Is it possible ?

Thanks, NiCLO

2

There are 2 answers

0
fadden On

You can send the frames to a SurfaceTexture you create, rather than one that's part of TextureView, then get the pixels by rendering them to a GLES pbuffer and reading them back with glReadPixels().

If you can work in YUV rather than RGB, you can get to the data faster and more simply by directing the Camera2 output to an ImageReader.

Grafika has some useful examples, e.g. "texture from camera".

1
Hpsaturn On

For me, the next implementation works fine for me:

    Bitmap bitmap = mTextureView.getBitmap(mWidth, mHeight);
    int[] argb = new int[mWidth * mHeight];
    // get ARGB pixels and then proccess it with 8UC4 OpenCV convertion
    bitmap.getPixels(argb, 0, mWidth, 0, 0, mWidth, mHeight);
    // native method (NDK or CMake)
    processFrame8UC4(argb, mWidth, mHeight);

A complete implementation for Camera API2 and NDK (OpenCV) here: https://stackoverflow.com/a/49331546/471690