0

I have a code that show camera with SurfaceView and capture image from that camera.
Now i want to show 4 camera with SurfaceView together and capture image when touch each one of them.
Camera ids are 2, 3, 4, 5.
I read and use these links:
Capture screen of SurfaceView
how to create and save a screenshot from a surfaceview?
This is my code:

package com.example.foosurface;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;
    
public class MainActivity extends Activity implements SurfaceHolder.Callback {

    protected static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
    private SurfaceView SurView;
    private SurfaceHolder camHolder;
    private boolean previewRunning;
    public static Camera camera = null;
    private RelativeLayout CamView;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        CamView = (RelativeLayout) findViewById(R.id.camview);//RELATIVELAYOUT OR
        //ANY LAYOUT OF YOUR XML

        SurView = (SurfaceView)findViewById(R.id.sview);//SURFACEVIEW FOR THE PREVIEW
        //OF THE CAMERA FEED
        camHolder = SurView.getHolder();                           //NEEDED FOR THE PREVIEW
        camHolder.addCallback(this);                               //NEEDED FOR THE PREVIEW
        camHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//NEEDED FOR THE PREVIEW

        Button btn = (Button) findViewById(R.id.button1); //THE BUTTON FOR TAKING PICTURE

        btn.setOnClickListener(new View.OnClickListener() {    //THE BUTTON CODE
            public void onClick(View v) {
                camera.takePicture(shutterCallback, rawCallback, jpegCallback);//TAKING THE PICTURE
                //THE mPicture IS CALLED
                //WHICH IS THE LAST METHOD(SEE BELOW)
            }
        });

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,//NEEDED FOR THE PREVIEW
                               int height) {
        if(previewRunning) {
            camera.stopPreview();
        }
        Camera.Parameters camParams = camera.getParameters();
        Camera.Size size = camParams.getSupportedPreviewSizes().get(0);
        camParams.setPreviewSize(size.width, size.height);
        camera.setParameters(camParams);
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
            previewRunning=true;
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {                  //NEEDED FOR THE PREVIEW
        try {
            camera=Camera.open();
        } catch(Exception e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {             //NEEDED FOR THE PREVIEW
        camera.stopPreview();
        camera.release();
        camera=null;
    }


    ShutterCallback shutterCallback = new ShutterCallback() {
        public void onShutter() {
            Log.d("TAG", "onShutter'd");
        }
    };

    /** Handles data for raw picture */
    PictureCallback rawCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.d("TAG", "onPictureTaken - raw");
        }
    };

    /** Handles data for jpeg picture */
    PictureCallback jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {

            File myExternalFile = new File(Environment.getExternalStorageDirectory()+
                    File.separator+"Ultimate Entity Detector");
            File tmpFile = new File(myExternalFile,"TempGhost.jpg");
            try {
                tmpFile.delete();
                tmpFile.createNewFile();
                FileOutputStream output = new FileOutputStream(tmpFile);
                output.write(data);
                output.flush();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    };
}

My xml code :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:id="@+id/camview">

    <SurfaceView
        android:id="@+id/sview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/button1"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />


</RelativeLayout>

My question:
How to show 4 camera preview together with surfaceview and capture image from them?

Mohsen
  • 63
  • 1
  • 5
  • Why not use a LinearLayout that have width and height as much as a parent and has vertical orientation, inside it, put 2 more linear layouts which have width as parent and height as wrap_content, making their orientation horizontal and inside them each one of them you put the relative layout that you call camview – Dan Baruch Nov 02 '20 at 07:53
  • @DanBaruch its not my problem. its ok to use LinearLayout. but my problem is how to use callback for each camera and how to define camera.takePicture for each camera holder. – Mohsen Nov 02 '20 at 08:00
  • In your code, you find the view of the camera and set everything you need for it. If you have 4 different views, each with a unique ID, and use the same code for each? Won't that work? – Dan Baruch Nov 02 '20 at 08:03
  • @DanBaruch i set everything for 4 different in my code, but i want to show and control 4 camera together and release every one i want and active every one when i want. – Mohsen Nov 07 '20 at 06:56

1 Answers1

0

I found my answer, i used holder.addCallback for each holder. it's one holder callback:

sHolder[0].addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                try {
                    mCamera[0] =Camera.open(2);
                } catch(Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getActivity(),"Error",Toast.LENGTH_LONG).show();
                    getActivity().finish();
                }
                openAndStartCamera(0);
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
                if(previewRunning[0]) {
                    mCamera[0].stopPreview();
                }
                Camera.Parameters camParams0 = mCamera[0].getParameters();
                Camera.Size size0 = camParams0.getSupportedPreviewSizes().get(0);
                camParams0.setPreviewSize(size0.width, size0.height);
                mCamera[0].setParameters(camParams0);
                try {
                    mCamera[0].setPreviewDisplay(sHolder[0]);
                    mCamera[0].startPreview();
                    previewRunning[0]=true;
                } catch(IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                mCamera[0].stopPreview();
                mCamera[0].release();
                mCamera[0]=null;
                previewRunning[0]=false;
                Log.e(TAG,"release camera");
            }
        });
Mohsen
  • 63
  • 1
  • 5