28

Is it possible to capture an image without showing the camera preview?, i have a requirement that i should be able to capture the image from a thread or from a service, without disturbing the foreground application, where i do not want to show the camera preview, but still i want to capture the image in background and store it in the device

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
city0666
  • 427
  • 1
  • 7
  • 13
  • 2
    Have you seen these other questions? http://stackoverflow.com/questions/2386025/android-camera-without-preview http://stackoverflow.com/questions/7398897/how-to-use-camera-to-take-picture-in-a-background-service-on-android – Eric Brynsvold Mar 16 '12 at 21:44
  • any example program to give using front camera without preview & save sd card – city0666 Mar 16 '12 at 21:52

5 Answers5

14

Try this code. It will click a picture when the activity starts up. It has a preview, but the preview size is set to 0 by 0 dp.

package fortyonepost.com.pwop;

import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView;

public class TakePicture extends Activity implements SurfaceHolder.Callback
{
    //a variable to store a reference to the Image View at the main.xml file
    private ImageView iv_image;
    //a variable to store a reference to the Surface View at the main.xml file
    private SurfaceView sv;

    //a bitmap to display the captured image
    private Bitmap bmp;

    //Camera variables
    //a surface holder
    private SurfaceHolder sHolder;
    //a variable to control the camera
    private Camera mCamera;
    //the camera parameters
    private Parameters parameters;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        //get the Image View at the main.xml file
        iv_image = (ImageView) findViewById(R.id.imageView);

        //get the Surface View at the main.xml file
        sv = (SurfaceView) findViewById(R.id.surfaceView);

        //Get a surface
        sHolder = sv.getHolder();

        //add the callback interface methods defined below as the Surface View callbacks
        sHolder.addCallback(this);

        //tells Android that this surface will have its data constantly replaced
        sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
    {
         //get camera parameters
         parameters = mCamera.getParameters();

         //set camera parameters
         mCamera.setParameters(parameters);
         mCamera.startPreview();

         //sets what code should be executed after the picture is taken
         Camera.PictureCallback mCall = new Camera.PictureCallback()
         {
             @Override
             public void onPictureTaken(byte[] data, Camera camera)
             {
                 //decode the data obtained by the camera into a Bitmap
                 bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
                 //set the iv_image
                 iv_image.setImageBitmap(bmp);
             }
         };

         mCamera.takePicture(null, null, mCall);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        // The Surface has been created, acquire the camera and tell it where
        // to draw the preview.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);

        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        //stop the preview
        mCamera.stopPreview();
        //release the camera
        mCamera.release();
        //unbind the camera from this object
        mCamera = null;
    }
}

reference: http://www.41post.com/3794/programming/android-take-a-picture-without-displaying-a-preview

Majid Golshadi
  • 2,686
  • 2
  • 20
  • 29
Arjun S Lal
  • 141
  • 5
  • This is on the right track, but you're using an `Activity` rather than a background thread or service. – Sam Nov 22 '14 at 23:20
  • This takes a picture, but it is rotated 90 degrees ! To check, I made the surface view 200x200 pixels instead of 0 width. The surface view also displays the image sideways. – Raja Feb 17 '17 at 18:26
4

i could not get accepted answer to work within my main activity (it worked as a separate activity when i changed surface view to 1dpi by 1dpi, but after taking photo, my dynamic views would disappear).

to take photo without preview in my main activity, i used the code from Android - Take picture without preview (modified version follows).

...

private SurfaceView sv;
Camera myCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);

...

private void takePhoto() {

        Camera.Parameters parameters = myCamera.getParameters();
        // myCamera.setDisplayOrientation(180);
        // parameters.setPictureFormat(ImageFormat.JPEG);
        // parameters.setPictureFormat(PixelFormat.JPEG);
        myCamera.setParameters(parameters);
        SurfaceView mview = sv;
        try {
            myCamera.setPreviewDisplay(mview.getHolder());
            myCamera.startPreview();
            myCamera.takePicture(null, null, photoCallback);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {

            saveMyPhotoToParse(data);
            // Log.i(DEBUG_TAG,"image pseudo saved");
        }
    };
Community
  • 1
  • 1
tmr
  • 1,500
  • 15
  • 22
2

Make the preview inside another linear layout and change the alpha values 255 full transparent 0 full opaque

cameraPreview_holderLL.setAlpha(255);// enable preview

cameraPreview_holderLL.setAlpha(0);//disable preview

<LinearLayout
     android:id="@+id/camera_preview_holder"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
        <LinearLayout
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >
        </LinearLayout>
</LinearLayout>
Pranoy Sarkar
  • 1,965
  • 14
  • 31
1

you can use a dummy surfaceholder.callback

private SurfaceHolder.Callback dummySurfaceCallback = new SurfaceHolder.Callback()
{

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        // do nothing
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        // do nothing
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        // do nothing
    }
};

and apply it to a surfaceholder(previewHolder)

    preview = (SurfaceView) findViewById(R.id.preview);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(dummySurfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

and then use the previewholder in setting up previewdisplay in mediarecoreder.

    mediaRecorder.setPreviewDisplay(previewHolder.getSurface());

this method will have you a black screen preview. this works for me, i hope this will help...

niczm25
  • 169
  • 1
  • 2
  • 13
0

Pass new surface object as frame, in java like(new Surface()) in kotlin when surface is required pass Surface() Surface is option to show your camera preview. In some condition preview is not required like take shoot or record video in background. When this state, you should pass newly surface.

In Video Recording: mediaRecorder.setPreviewDisplay(new Surface());

On Capture Image: mCamera.setPreviewDisplay(new Surface());

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 07 '22 at 06:30