How to take a photo using CameraSource?

10,423

Solution 1

Try using this way (i'm using OCR from Google Vision and for taking picture with CameraSource) Pd: the flash button i havent fix it yet...

YOU HAVE TO USE : compile 'com.google.android.gms:play-services-vision:9.2.1' in your dependecies for the OCR compatibility

public class CustomCamaraActivity extends BaseActivity implements Callback,
    OnClickListener {

private Context context;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private Button flipCamera;
private Button flashCameraButton;
private Button captureImage;
private Button BtnCapturarFoto;
private int cameraId;
private boolean flashmode = false;
private int rotation;
private ActionBar actionBar;
private CameraSource cameraSource;
private StringBuilder builder;
private TextView txTextoCapturado;


private static CustomCamaraActivity instance;
private Activity activity;
private String nombreProyecto;
public static final int REQUEST_IMAGE_CAPTURE = 0020;
private File file;
private String ubicacion;
private static final String TAG = "FOTOGRAFIA";
private int Height = 620, Width = 480;
private TextRecognizer recognizer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.custom_camara_layout);
    context = this;
    // camera surface view created
    cameraId = CameraInfo.CAMERA_FACING_BACK;
    flipCamera = (Button) findViewById(R.id.flipCamera);
    flashCameraButton = (Button) findViewById(R.id.flash);
    captureImage = (Button) findViewById(R.id.captureImage);
    BtnCapturarFoto = (Button) findViewById(R.id.btnCapturarFoto);
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    txTextoCapturado = (TextView) findViewById(R.id.tvTextoCapturado);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    flipCamera.setOnClickListener(this);
    captureImage.setOnClickListener(this);
    flashCameraButton.setOnClickListener(this);
    BtnCapturarFoto.setOnClickListener(this);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    /*if (Camera.getNumberOfCameras() > 1) {
        flipCamera.setVisibility(View.VISIBLE);
    }*/
    if (!getBaseContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH)) {
        flashCameraButton.setVisibility(View.GONE);
        flipCamera.setVisibility(View.GONE);
    }


    recognizer = new TextRecognizer.Builder(getApplicationContext()).build();
    if (recognizer.isOperational()) {

        cameraSource = new CameraSource.Builder(getApplicationContext(), recognizer)
                .setFacing(CameraSource.CAMERA_FACING_BACK)
                .setRequestedPreviewSize(1280, 1024)
                .setRequestedFps(15.0f)
                .setAutoFocusEnabled(true)
                .build();

        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(CustomCamaraActivity.this, new String[]{Manifest.permission.CAMERA}, 100);
                    return;
                }
                try {
                    releaseCamera();
                    cameraSource.start(surfaceView.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if(cameraSource != null){
                    cameraSource.stop();
                }
            }
        });
        recognizer.setProcessor(new Detector.Processor<TextBlock>() {
            @Override
            public void release() {

            }

            @Override
            public void receiveDetections(Detector.Detections<TextBlock> detections) {
                final SparseArray<TextBlock> items = detections.getDetectedItems();
                if (items.size() != 0) {
                    builder = new StringBuilder();
                    for (int i = 0; i < items.size(); i++) {
                        TextBlock it = items.valueAt(i);
                        builder.append(it.getValue());
                    }
                    final String read = builder.toString().trim();
                    //String read = builder.toString().trim().replace(" ", "").replace("\n", "");
                    try{
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                txTextoCapturado.setText(read);
                            }
                        });
                    }catch (Exception ex){
                        Log.e("error","Error al actualizar texto OCR");
                    }

                    //It continues doing other things here
                }
            }
        });
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 100:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                try {
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    cameraSource.start(surfaceView.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            break;
    }
}


public String getUbicacion() {
    return ubicacion;
}

@Override
protected void onResume() {
    super.onResume();
}

@Override
protected void onPause() {
    super.onPause();
    if (camera != null) {
        camera.setPreviewCallback(null);
        camera.setErrorCallback(null);
        camera.stopPreview();
        camera.release();
        camera = null;
    }
}

@Override
public void onBackPressed() {
    super.onBackPressed();
    if(camera != null){
        camera.setPreviewCallback(null);
        camera.setErrorCallback(null);
        camera.stopPreview();
        camera.release();
        camera = null;
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (!openCamera(CameraInfo.CAMERA_FACING_BACK)) {
        alertCameraDialog();
    }

}

private boolean openCamera(int id) {
    boolean result = false;
    cameraId = id;
    //releaseCamera();
    try {
        camera = Camera.open(cameraId);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (camera != null) {
        try {
            setUpCamera(camera);
            camera.setErrorCallback(new ErrorCallback() {

                @Override
                public void onError(int error, Camera camera) {

                }
            });
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
            releaseCamera();
        }
    }
    return result;
}

private void setUpCamera(Camera c) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, info);
    rotation = getWindowManager().getDefaultDisplay().getRotation();
    int degree = 0;
    switch (rotation) {
        case Surface.ROTATION_0:
            degree = 0;
            break;
        case Surface.ROTATION_90:
            degree = 90;
            break;
        case Surface.ROTATION_180:
            degree = 180;
            break;
        case Surface.ROTATION_270:
            degree = 270;
            break;

        default:
            break;
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        // frontFacing
        rotation = (info.orientation + degree) % 330;
        rotation = (360 - rotation) % 360;
    } else {
        // Back-facing
        rotation = (info.orientation - degree + 360) % 360;
    }
    c.setDisplayOrientation(rotation);
    Parameters params = c.getParameters();

    showFlashButton(params);

    List<String> focusModes = params.getSupportedFlashModes();
    if (focusModes != null) {
        if (focusModes
                .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            params.setFlashMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }
    }

    params.setRotation(rotation);
}

private void showFlashButton(Parameters params) {
    boolean showFlash = (getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH) && params.getFlashMode() != null)
            && params.getSupportedFlashModes() != null
            && params.getSupportedFocusModes().size() > 1;

    flashCameraButton.setVisibility(showFlash ? View.VISIBLE
            : View.INVISIBLE);

}

private void releaseCamera() {
    try {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.setErrorCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("error", e.toString());
        camera = null;
    }
}

private void releaseCameraSource() {
    try {
        if (cameraSource != null) {
            cameraSource.stop();
            cameraSource.release();
            cameraSource = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("error", e.toString());
        cameraSource = null;
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
                           int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.flash:
            flashOnButton();
            break;
        case R.id.flipCamera:
            flipCamera();
            break;
        case R.id.captureImage:
            takeImage();
            break;
        case R.id.btnCapturarFoto:
            takeImage();
            break;

        default:
            break;
    }
}

private void takeImage() {
    try{
        //openCamera(CameraInfo.CAMERA_FACING_BACK);
        //releaseCameraSource();
        //releaseCamera();
        //openCamera(CameraInfo.CAMERA_FACING_BACK);
        //setUpCamera(camera);
        //Thread.sleep(1000);
        cameraSource.takePicture(null, new CameraSource.PictureCallback() {

            private File imageFile;
            @Override
            public void onPictureTaken(byte[] bytes) {
                try {
                    // convert byte array into bitmap
                    Bitmap loadedImage = null;
                    Bitmap rotatedBitmap = null;
                    loadedImage = BitmapFactory.decodeByteArray(bytes, 0,
                            bytes.length);

                    // rotate Image
                    Matrix rotateMatrix = new Matrix();
                    rotateMatrix.postRotate(rotation);
                    rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
                            loadedImage.getWidth(), loadedImage.getHeight(),
                            rotateMatrix, false);
                    String state = Environment.getExternalStorageState();
                    File folder = null;
                    if (state.contains(Environment.MEDIA_MOUNTED)) {
                        folder = new File(Environment
                                .getExternalStorageDirectory() + "/Demo");
                    } else {
                        folder = new File(Environment
                                .getExternalStorageDirectory() + "/Demo");
                    }

                    boolean success = true;
                    if (!folder.exists()) {
                        success = folder.mkdirs();
                    }
                    if (success) {
                        java.util.Date date = new java.util.Date();
                        imageFile = new File(folder.getAbsolutePath()
                                + File.separator
                                //+ new Timestamp(date.getTime()).toString()
                                + "Image.jpg");

                        imageFile.createNewFile();
                    } else {
                        Toast.makeText(getBaseContext(), "Image Not saved",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }

                    ByteArrayOutputStream ostream = new ByteArrayOutputStream();

                    // save image into gallery
                    rotatedBitmap = resize(rotatedBitmap, 800, 600);
                    rotatedBitmap.compress(CompressFormat.JPEG, 100, ostream);

                    FileOutputStream fout = new FileOutputStream(imageFile);
                    fout.write(ostream.toByteArray());
                    fout.close();
                    ContentValues values = new ContentValues();

                    values.put(Images.Media.DATE_TAKEN,
                            System.currentTimeMillis());
                    values.put(Images.Media.MIME_TYPE, "image/jpeg");
                    values.put(MediaStore.MediaColumns.DATA,
                            imageFile.getAbsolutePath());

                    CustomCamaraActivity.this.getContentResolver().insert(
                            Images.Media.EXTERNAL_CONTENT_URI, values);

                    setResult(Activity.RESULT_OK); //add this
                    finish();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

    }catch (Exception ex){
        txTextoCapturado.setText("Error al capturar fotografia!");
    }

}

private void flipCamera() {
    int id = (cameraId == CameraInfo.CAMERA_FACING_BACK ? CameraInfo.CAMERA_FACING_FRONT
            : CameraInfo.CAMERA_FACING_BACK);
    if (!openCamera(id)) {
        alertCameraDialog();
    }
}

private void alertCameraDialog() {
    AlertDialog.Builder dialog = createAlert(CustomCamaraActivity.this,
            "Camera info", "error to open camera");
    dialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();

        }
    });

    dialog.show();
}

private Builder createAlert(Context context, String title, String message) {

    AlertDialog.Builder dialog = new AlertDialog.Builder(
            new ContextThemeWrapper(context,
                    android.R.style.Theme_Holo_Light_Dialog));
    dialog.setIcon(R.drawable.ic_launcher);
    if (title != null)
        dialog.setTitle(title);
    else
        dialog.setTitle("Information");
    dialog.setMessage(message);
    dialog.setCancelable(false);
    return dialog;

}

private void flashOnButton() {
    if (camera != null) {
        try {
            Parameters param = camera.getParameters();
            if (flashmode) {
                param.setFlashMode(Parameters.FLASH_MODE_OFF);
                flashCameraButton.setBackground(getResources().getDrawable(R.drawable.ic_flash_off));
            } else {
                param.setFlashMode(Parameters.FLASH_MODE_TORCH);
                flashCameraButton.setBackground(getResources().getDrawable(R.drawable.ic_flash_on));
            }
            //param.setFlashMode(!flashmode ? Parameters.FLASH_MODE_TORCH : Parameters.FLASH_MODE_OFF);
            camera.setParameters(param);
            flashmode = !flashmode;
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }

    }
}

/**
 * Metodo para cambiar el tamaño de la fotografia una resolucion predeterminada.
 *
 * @param image
 * @param maxWidth
 * @param maxHeight
 * @return
 */
private Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
    if (maxHeight > 0 && maxWidth > 0) {
        int width = image.getWidth();
        int height = image.getHeight();
        float ratioBitmap = (float) width / (float) height;
        float ratioMax = (float) maxWidth / (float) maxHeight;

        int finalWidth = maxWidth;
        int finalHeight = maxHeight;
        if (ratioMax > 1) {
            finalWidth = (int) ((float) maxHeight * ratioBitmap);
        } else {
            finalHeight = (int) ((float) maxWidth / ratioBitmap);
        }
        image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
        return image;
    } else {
        return image;
    }
}

}

and here is the layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">

    <TextView
        android:id="@+id/tvTextoCapturado"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        android:textColor="@color/white"
        android:textSize="18sp"
        android:textStyle="bold" />
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="10dp"
    android:elevation="0dp"
    android:orientation="horizontal"
    android:weightSum="30">

    <Button
        android:id="@+id/flash"
        android:layout_width="60dp"
        android:layout_height="40dp"
        android:layout_alignBaseline="@+id/captureImage"
        android:layout_alignBottom="@+id/captureImage"
        android:layout_marginLeft="27dp"
        android:layout_marginRight="27dp"
        android:layout_toLeftOf="@+id/captureImage"
        android:layout_toStartOf="@+id/captureImage"
        android:layout_weight="4"
        android:background="@drawable/ic_flash_off"
        android:gravity="center" />

    <Button
        android:id="@+id/captureImage"
        android:layout_width="35dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="27dp"
        android:layout_marginRight="27dp"
        android:layout_weight="10"
        android:background="@android:drawable/ic_menu_camera"
        android:visibility="gone" />

    <Button
        android:id="@+id/btnCapturarFoto"
        style="@style/blue_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="27dp"
        android:layout_marginRight="27dp"
        android:layout_weight="20"
        android:elevation="0dp"
        android:text="Tomar fotografia" />

    <Button
        android:id="@+id/flipCamera"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="27dp"
        android:layout_marginRight="27dp"
        android:layout_toRightOf="@id/captureImage"
        android:layout_weight="4"
        android:background="@drawable/ic_rotate"
        android:visibility="invisible" />

</LinearLayout>

Solution 2

You can achieve it by CameraSource class like this:

mCameraSource = builder
                .setFlashMode(if (useFlash) Camera.Parameters.FLASH_MODE_TORCH else null)
                .build()

Add below code to the button click listener:

mCameraSource.takePicture(null, CameraSource.PictureCallback { data ->
   // here data is a byteArray, you can play with it :)
}
Share:
10,423
suffuko
Author by

suffuko

Updated on June 13, 2022

Comments

  • suffuko
    suffuko almost 2 years

    I'm having some problems with CameraSource when I want to take a picture using the camera. All i want is take a picture with a button i made on the xml file and use 'CameraSource' to take the photo because i'm using 'TextRecognizer' too. The Camera is working fine but the problem occurs when i press the button to take a picture.

    Manifest File:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    My Variables:

    SurfaceView cameraView;
    TextView textView;
    CameraSource camera_source;
    final int RequestCameraPermissionID = 1001;
    

    Class:

    // Starting the CameraSource. This will be in the 'OnCreate' function. This function works.
    private void OpenCameraSource(){
            final TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
            if (!textRecognizer.isOperational()) {
                Log.w("Steal_Activity", "Detector activity are not yet available");
                Toast.makeText(getApplicationContext(),"Detector activity are not yet available",Toast.LENGTH_SHORT).show();
            } else {
                camera_source = new CameraSource.Builder(getApplicationContext(),textRecognizer)
                        .setFacing(CameraSource.CAMERA_FACING_BACK)
                        .setRequestedPreviewSize(1280, 1024)
                        .setRequestedFps(2.0f)
                        .setAutoFocusEnabled(true)
                        .build();
                cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
                    @Override
                    public void surfaceCreated(SurfaceHolder surfaceHolder) {
                        try {
                            if (ActivityCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                                ActivityCompat.requestPermissions(Steal.this,
                                        new String[]{android.Manifest.permission.CAMERA},
                                        RequestCameraPermissionID);
                                return;
                            }
                            camera_source.start(cameraView.getHolder());
                        }catch (IOException ex){
                            ex.printStackTrace();
                        }
                    }
                    @Override
                    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                    }
                    @Override
                    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                        camera_source.stop();
                    }
                });
                textRecognizer.setProcessor(new Detector.Processor<TextBlock>() {
                    // Some Stuff here
                }
            });
        }
    }
    
    
    // This function will be launched when the button is pressed
    public void OnClick_TakeShot(View view){
            try{//I GET ERROR HERE
                camera_source.takePicture(null,pictureCallback);
            }catch (Exception ex){
                Toast.makeText(getApplicationContext(),"Error:"+ex.toString(),Toast.LENGTH_LONG).show();
            }
    }
    
    // Callback for 'takePicture'
    CameraSource.PictureCallback pictureCallback = new CameraSource.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] bytes) {
                File file_image = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+"/pics");
                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0, bytes .length);
                if(bitmap!=null){
                    if(!file_image.isDirectory()){
                        file_image.mkdir();
                    }
                    file_image=new File(file_image,"mylastpic.jpg");
                    try{
                        FileOutputStream fileOutputStream=new FileOutputStream(file_image);
                        bitmap.compress(Bitmap.CompressFormat.JPEG,100, fileOutputStream);
                        fileOutputStream.flush();
                        fileOutputStream.close();
                    }
                    catch(Exception exception) {
                        Toast.makeText(getApplicationContext(),"Error saving: "+ exception.toString(),Toast.LENGTH_LONG).show();
                    }
                }
            }
    };
    

    NOT WORKING WHEN I PRESS THE BUTTON TO TAKE PICTURE enter image description here