How to take pictures from the camera without previ

2020-01-27 18:49发布

问题:

Now all I want is an app that just takes the picture from the camera upon launching. No layout, no camera preview...nothing, just a simple app icon to launch the app. Once launched the camera should take the picture.

Here is the preview image, that i do not want to appear in my app. I just want to eanble my app to click the take picture button encircled in the image here:

Once the picture is taken then I need to save it in my photo gallery.

Can someone guide me here? Thanks

Here is some code that I have tried on emulator and device.

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.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;

public class Main extends Activity implements SurfaceHolder.Callback{

    private Camera camera;
     private ImageButton cameraClick;
     private SurfaceHolder mHolder; 

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

      SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
      mHolder = surfaceView.getHolder();
      mHolder.addCallback(this);
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  

      cameraClick = (ImageButton) findViewById(R.id.cameraClick);
      cameraClick.setOnClickListener( new OnClickListener() {
       public void onClick(View v)
       {
            camera.takePicture(shutterCallback, rawCallback,jpegCallback);
       }
      });  





      }

     // Handles when shutter open
     ShutterCallback shutterCallback = new ShutterCallback()
     {
      public void onShutter()
      {   

      }
     };

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

      }
     }; 

     /** Handles data for jpeg picture */
     PictureCallback jpegCallback = new PictureCallback()
    {
      public void onPictureTaken(byte[] data, Camera camera)
    {
       // we do something using return byte[] of taken image.
      }
     };

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

      // Set camera preview size,orientation,rotation using parameters 

    Camera.Parameters parameters = camera.getParameters();
            parameters.set("orientation", "portrait");
            camera.setParameters(parameters);
             camera.startPreview();       

     }

     @Override
     public void surfaceCreated(SurfaceHolder holder)
    {
      camera = Camera.open();
             try {
        camera.setPreviewDisplay(holder);
       }
    catch (IOException e)
    {
        e.printStackTrace();
       }

     }

     @Override
     public void surfaceDestroyed(SurfaceHolder holder)
    {
      camera.stopPreview();
             camera.release();
            camera = null; 

     }

}

Now I am able to hear the picture click on the button click both on the emulator and the device. Now I want to save the picture as well. Any clue?

回答1:

Use below code. Its Tested and Worked for me. Any issues please feel free to put comments.

private void takeSnapShots()
{
      Toast.makeText(getApplicationContext(), "Image snapshot   Started",Toast.LENGTH_SHORT).show();
     // here below "this" is activity context.  
 SurfaceView surface = new SurfaceView(this);
    Camera camera = Camera.open();
    try {
        camera.setPreviewDisplay(surface.getHolder());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    camera.startPreview();
    camera.takePicture(null,null,jpegCallback);
}


 /** picture call back */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) 
{
    FileOutputStream outStream = null;
    try {
  String dir_path = "";// set your directory path here
        outStream = new FileOutputStream(dir_path+File.separator+image_name+no_pics+".jpg");    
        outStream.write(data);
        outStream.close();
        Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally 
    {
        camera.stopPreview();
        camera.release();
        camera = null;
        Toast.makeText(getApplicationContext(), "Image snapshot Done",Toast.LENGTH_LONG).show();


    }
    Log.d(TAG, "onPictureTaken - jpeg");
}
};


回答2:

As of API-Level 11 the SurfaceTexture was added. With it a SurfaceView is no longer needed. I tested the following code with my Samsung Galaxy S3 Neo.

mCamera = Camera.open();
try {
    mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e1) {
    Log.e(Version.APP_ID, e1.getMessage());
}

Parameters params = mCamera.getParameters();
params.setPreviewSize(640, 480);
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
params.setPictureFormat(ImageFormat.JPEG);
mCamera.setParameters(params);
mCamera.startPreview();
mCamera.takePicture(null, null, null, new PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.i(Version.APP_ID, "picture-taken");
    }
});


回答3:

The camera preview is just a special kind of View in your layout, so if you don't want to display it but still use your existing code without a lot of modifications, there are some tricks you can do.

For example, in your layout file where you're adding the camera preview SurfaceView, you can just add another view on top of it to block the preview. That way you'll still be able to use your existing code without modifying too much and the camera preview will work just like it did before, but you'll have the effect you're looking for which is not showing the camera preview.



回答4:

I've tried exactly what you need before and after alot of research found out that for some reason you must have a preview started and even showing that content in a SurfaceView to be able to get the picture, apparently the system behind the scenes flushes whatever is in the buffer for the SurfaceView rendering the preview, now what I did to overcome this issue (taking the picture without preview) was just to set the SurfaceView in my layout to 1dp width and 1dp height (notice it has to be 1dp, 0dp will cause a crash).

<SurfaceView
   android:layout_width="1dp"
   android:layout_height="1dp"/>

It definitely might not be a very elegant way to get rid of the "preview" Image but it definitely does the trick and left me room to do everything else I had in mind.

Hope this helps...

Regards



回答5:

For those who are looking for doing the same thing, but with CAMERA 2 API, you could check my answer here. Capture picture without preview using camera2 API.