Take picture in android - android

Is it possible to take a picture with out opening camera ? I tried with intents but its opening camera, but i don't want to open camera.I tried following
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, 1);
and after that receiving the activity.But how to do with out opening the camera?

Yes it is possible for that use SurfaceHolder.Callback Interface .
And
#TargetApi(9)
public void surfaceCreated(SurfaceHolder holder){
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open(CaptureCameraImage.cameraID);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
if (mPreviewRunning){
mCamera.stopPreview();
}
try{
mCamera.setPreviewDisplay(holder);
}catch (Exception e){
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
//mCamera.stopPreview();
//mPreviewRunning = false;
//mCamera.release();
}
For that use dummy surfaceview so you can take picture from background.
like
SurfaceView dummy=new SurfaceView(context);
dummy.addCallback(this);
And do some reasearch work on this dummy Surfaceview.

Related

Capturing Photo from SurfaceView

I'm trying to capture an image from a SurfaceView custom camera. I have set up the initial code but I don't know how to call the 'take photo' method so that I can see the preview on the surface.
Currently this code displays the preview in realtime. I need to take the picture and access the byte[] array
Please help me complete the code:
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
captureImage = (ImageButton) findViewById(R.id.captureImage);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
captureImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//this button press should take the picture
}
});
mSurfaceView.getHolder().addCallback(this);
mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera = Camera.open();
}
#Override
public void onPause() {
super.onPause();
mCamera.stopPreview();
}
#Override
public void onDestroy() {
super.onDestroy();
mCamera.release();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mSurfaceView.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
params.setPreviewSize(selected.width,selected.height);
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
I need to get the bytes [] data so that I can convert the image to a base64 string. How do I call the necessary methods to take the picture using the code above?
Check "jpegCallback" in my example:
public class CameraActivity extends ActionBarActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
PictureCallback jpegCallback;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", 2000).show();
refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
// open the camera
camera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
List<Camera.Size> sizes = param.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
param.setPreviewSize(selected.width,selected.height);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
}

camera preview showing black screen

Hi I am developing an android app trying out custom camera and video functionality. The problem is when I try to return to the Cameraview onClick of a button in Videoview , the preview is not displayed. It shows only the black screen.
onClick in Videoview is as below
try
{
Thread.sleep(1000);
recorder.stop();
recorder.reset();
recorder.release();
}
catch (Exception e)
{
e.printStackTrace();
}
camera.release();
startActivity(new Intent(Video.this,Camera.class));
finish();
The camera is null onSurfaceChanged of the Cameraview on returning from Videoview.
#Override
public void surfaceChanged(SurfaceHolder sHolder, int format, int width, int height)
{
Log.e("surfaceChanged","camera");
if(camera != null)
{
initPreview(width, height);
camera.startPreview();
}
else if(camera == null)
{
try
{
Camera camera = Camera.open(currentCameraId);
if (holder.getSurface() == null)
{
return;
}
try
{
//camera.stopPreview();
//camera.reconnect();
//camera.lock();
//camera.unlock();
camera.setPreviewCallback(this);
camera.setPreviewDisplay(holder);
}
catch (Exception e)
{
}
initPreview(width, height);
camera.startPreview();
}
catch (Exception e)
{
releaseCamera();
}
Not sure where I am going wrong. I am not able to open camera or reconnect it. Please Help.
Thanks!
Try this:
1) Set callBack for SurfaceView.
public CameraView(Context ctx, AttributeSet attrSet) {
super(ctx, attrSet);
getHolder().addCallback(cameraPreviewCallback);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
};
2) Start camera
camera = Camera.open();
camera.setPreviewCallback(cameraPreviewCallback);
camera.setPreviewDisplay(getHolder());
camera.startPreview();

Android: Taking pictures programmatically is not working

I do not have much experience with the Camera functionality in Android. I need to take a photo through code which I am planning to send back to a server. I based my logic off of this post and it works well as long as I do not add mCamera.takePicture(null, null, mPictureCallback); to the end of the surfaceChange method (which is what I want I guess). When I do add that line, it works sometimes but most of the times, I just get back a black screen. This is the main problem. I don't think there is a compatibility issue with the device because I got this functionality working atleast 3-4 times earlier.
My device that I am testing on is Galaxy Nexus
public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener
{
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
Log.e(TAG, "onCreate");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera_view);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if (data != null)
{
//Intent mIntent = new Intent();
//mIntent.putExtra("image",imageData);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
try
{
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts);
bitmap = Bitmap.createScaledBitmap(bitmap, 480, 480, false);
CameraProjectActivity.image.setImageBitmap(bitmap);
}
catch(Exception e)
{
e.printStackTrace();
}
//StoreByteImage(mContext, imageData, 50,"ImageName");
//setResult(FOTO_MODE, mIntent);
setResult(585);
finish();
}
}
};
protected void onResume()
{
Log.e(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}
protected void onStop()
{
Log.e(TAG, "onStop");
super.onStop();
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning)
{
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
List<Camera.Size> previewSizes = p.getSupportedPreviewSizes();
Camera.Size previewSize = previewSizes.get(3);
p.setPreviewSize(previewSize.width, previewSize.height);
mCamera.setParameters(p);
try
{
mCamera.setPreviewDisplay(holder);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
// THIS IS THE CODE THAT BREAKS IT. IS THERE ANY OTHER WAY TO DO THIS??? ********
// mCamera.takePicture(null, null, mPictureCallback);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
// mCamera.stopPreview();
// mPreviewRunning = false;
// mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
}
Any help would be appreciated.
Thanks!
I am not sure if this is a good solution, but I just fixed it by making the surfaceChanged() method synchronized and making the thread wait for a second just before I call takePicture.
try {
this.wait(1000);
mCamera.takePicture(null, null, mPictureCallback);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I believe that it is recommended to call startPreview() before setPreviewDisplay(), but this should not make a major difference.
What you see is that it takes time for the camera to initialize, and it cannot take a picture until it's ready. It's better to use a callback from camera to decide that it's ready, than to wait for arbitrary 1000 ms.
The callback you can use is a Camera.PreviewCallback. You can implement it in your CameraView class. To trigger the callback, simply add setOneShotPreviewCallback(this) to CameraView.surfaceChanged():
mCamera.startPreview();
mCamera.setPreviewDisplay(holder);
mCamera.setOneShotPreviewCallback(this);

getting null pointer exception on camera set parameters

I'm getting an error of a NullPointerException and it is referencing the line Camera.Parameters:
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w,
int h) {
// TODO Auto-generated method stub
Log.e(TAG, "surfaceChanged");
if (mPreviewRunning) {
mCamera.stopPreview();
mPreviewRunning = false;
Log.e(TAG, "stopPeview");
}
Camera.Parameters p = mCamera.getParameters();
Log.e(TAG, "paarameters");
p.setPreviewSize(w, h);
mCamera.setParameters(p);
Log.e(TAG, " set parameters");
try {
mCamera.setPreviewDisplay(holder);
Log.e(TAG, "setPreview");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
Could anyone tell me what the error is in the above code.
I will have to test it again to get the log, but here is the entire code. I did alter the manifest.
public class Picture extends Activity implements SurfaceHolder.Callback{
private String TAG;
private LayoutInflater mInflater = null;
private Camera mCamera;
boolean mPreviewRunning = false;
private SurfaceHolder mSurfaceHolder;
private SurfaceView mSurfaceView;
Button takepicture;
byte[] tempdata;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.camera_surface);
mCamera = getCameraInstance ();
mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mInflater = LayoutInflater.from(this);
View overView = mInflater.inflate(R.layout.cameraoverlay, null);
this.addContentView(overView, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
takepicture = (Button) findViewById(R.id.button);
takepicture.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
mCamera.takePicture(shutterCallback, mPictureCallback,
jpegCallback);
}
});
}
private Camera getCameraInstance() {
// TODO Auto-generated method stub
Camera mCamera = null;
try {
mCamera = Camera.open();
} catch (Exception e) {
}
return mCamera;
}
ShutterCallback shutterCallback = new ShutterCallback() {
#Override
public void onShutter() {}
};
PictureCallback mPictureCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {}
};
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
if(data != null) {
tempdata=data;
done();
}
}
};
void done(){
Bitmap bm = BitmapFactory.decodeByteArray(tempdata, 0, tempdata.length);
String url = Images.Media.insertImage(getContentResolver(),
bm, null, null);
bm.recycle();
Bundle bundle = new Bundle();
if(url!=null) {
bundle.putString("url", url);
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
} else {
Toast.makeText(this, "Picture can not be saved",
Toast.LENGTH_SHORT).show();
}
finish();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w,
int h) {
// TODO Auto-generated method stub
Log.e(TAG, "surfaceChanged");
if (mPreviewRunning) {
mCamera.stopPreview();
mPreviewRunning = false;
Log.e(TAG, "stopPeview");
}
Camera.Parameters p = mCamera.getParameters();
Log.e(TAG, "paarameters");
p.setPreviewSize(w, h);
mCamera.setParameters(p);
Log.e(TAG, " set parameters");
try {
mCamera.setPreviewDisplay(holder);
Log.e(TAG, "setPreview");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.e(TAG, "surfaceCreated");
try {
mCamera = Camera.open();
Log.e(TAG, "camera open");
} catch(Exception e) {}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
Also, the line the log referenced was the line: Camera.Parameters p = mCamera.getParameters();
Looks like mCamera is null... did you initialize it? (mCamera = Camera.open();)
See the docs for a checklist as it pertains to taking pictures
Add the below three lines in manifeast file::
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
To take pictures with this class, use the following steps:
1) Obtain an instance of Camera from open(int).
2) Get existing (default) settings with getParameters().
3) If necessary, modify the returned Camera.Parameters object and call
setParameters(Camera.Parameters).
4) If desired, call setDisplayOrientation(int).
5) Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder). Without a surface, the camera will be unable to start the preview.
6) Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture.
7) When you want, call takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback) to capture a photo. Wait for the callbacks to provide the actual image data.
8) After taking a picture, preview display will have stopped. To take more photos, call startPreview() again first.
9) Call stopPreview() to stop updating the preview surface.
10) Important: Call release() to release the camera for use by other applications. Applications should release the camera immediately in onPause() (and re-open() it in onResume()).
There are many solutions, but this is an easy, dead cheap option that worked for me:
try{
mCamera.autoFocus(autoFocusCB); //Or whatever part of code that crashes
}
catch(Exception e){
Log.v("joshtag","THIS PHONE DOES NOT SUPPORT AUTOFOCUS!!"); //a warning, popup, whatever
}
VoilĂ ! Trap deactivated.
Of course, dont forget the manifest permissions....

My custom camera happen to crash after taken a few photo why is that?

After taken a few photo, my camera just went black. Any suggestion of this?
SurfaceView cameraView;
SurfaceHolder surfaceHolder;
Camera camera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
cameraView = (SurfaceView)this.findViewById(R.id.CameraView);
surfaceHolder = cameraView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.addCallback(this);
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
public void onClick(View v){
camera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try{
OutputStream imageFileOS = new FileOutputStream(String.format("/sdcard/Galmix/%d.jpg",System.currentTimeMillis()));
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
} catch(FileNotFoundException e){
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
} catch (IOException e) {
Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
t.show();
}
camera.startPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
camera.startPreview();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try{
camera.setPreviewDisplay(holder);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureSize(640, 480);
if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
parameters.set("orientation", "portrait");
camera.setDisplayOrientation(90);
}
camera.setParameters(parameters);
} catch(IOException e){
camera.release();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
}
Check to make sure the images you're saving are being saved properly. I had a similar issue where due to a bug in my saving code I was getting a NullPointerException and killing my camera activity. For more specifics you'll have to post code though.

Categories

Resources