Failed to take picture using auto-focus - android

I have searched some solutions with my problem and sure there are many related issues regarding it but nothing solves my concern.
I am receiving a runtime exception : takepicture failed:native_autofocus..etc.
I tried to take picture from camera using autofocus and I can't seem to understand what could have caused the error.
Here is my code.
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mholder;
private Camera mcamera;
private Handler handler = new Handler();
public CameraPreview(Context context, Camera camera) {
super(context);
this.mcamera = camera;
mholder = getHolder();
mholder.addCallback(this);
mholder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (mholder.getSurface() == null) {
return;
}
try {
mcamera.stopPreview();
} catch (Exception e) {
Log.d("surfaceChanged", e.toString());
}
try {
mcamera.setPreviewDisplay(holder);
mcamera.startPreview();
} catch (IOException e) {
Log.d("surfaceChanged--->surfaceCreated", e.toString());
}
}
I think somethings is lacking in my runnable code, I tried to omit the runnable and execute autofocus once, it removed the runtime error. Did I missed to reinitialize something in this part?
private void autoFocus(Camera mcamera){
final Camera cam=mcamera;
handler.postDelayed(new Runnable() {
#Override
public void run() {
cam.autoFocus(autoFocusCallback);
handler.postDelayed(this, 1500L);
}
}, 1500L);
}
AutoFocusCallback autoFocusCallback=new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(null, null, mPicture);
}
};
private PictureCallback mPicture=new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
//do something
}
};
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mcamera.setPreviewDisplay(holder);
mcamera.startPreview();
mcamera.autoFocus(autoFocusCallback);
} catch (IOException e) {
Log.d("surfaceCreated", e.toString());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}

You didn't mention it but be sure to include the permission in your manifest.
< uses-feature android:name="android.hardware.camera.autofocus" />

Have a look here
or here
and you are calling autofocus on surfacecreated ,
It should be called on surface changed

Related

Camera is null when going back to activity

So I was following the android developers build a camera application sample and have my camera activity up and running. However when I go to another activity then hit the back button I am getting a crash because the camera is null in the surface view's on surface created. Can someone explain how this error is happening. Thanks!
** Activity
public class PhotoCaptureActivity extends AppCompatActivity implements View.OnClickListener{
public static final String TAG = "PhotoCaptureActivity";
CameraPreview mPreviewScreen;
Button mCaptureButton;
ImageView mPreviewThumbnail;
TextView mPhotoActionLabel;
TextView mImageLogText;
Camera mCamera;
Camera.PictureCallback mPicture;
ArrayList<Bitmap> mPictures = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_capture);
getSupportActionBar().hide();
mCaptureButton = (Button) findViewById(R.id.button_capture);
mPreviewThumbnail = (ImageView) findViewById(R.id.thumb_nail_image);
mPhotoActionLabel = (TextView) findViewById(R.id.photo_action_text);
mImageLogText = (TextView) findViewById(R.id.image_log);
mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
BitmapFactory.Options scalingOptions = new BitmapFactory.Options();
scalingOptions.inSampleSize = camera.getParameters().getPictureSize().width / mPreviewThumbnail.getMeasuredWidth();
final Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length, scalingOptions);
mPictures.add(bmp);
mPreviewThumbnail.setImageBitmap(bmp);
mPreviewThumbnail.setVisibility(ImageView.VISIBLE);
mCamera.startPreview();
mPhotoActionLabel.setText(getString(R.string.done));
}
};
mCaptureButton.setOnClickListener(this);
mPhotoActionLabel.setOnClickListener(this);
mImageLogText.setOnClickListener(this);
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
e.printStackTrace();
}
return c; // returns null if camera is unavailable
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_capture:
mCamera.takePicture(null, null, mPicture);
break;
case R.id.photo_action_text:
if (mPhotoActionLabel.getText().toString().equalsIgnoreCase(getString(R.string.cancel)))
finish();
else {
Intent photoReviewIntent = new Intent(this,PhotoReviewActivity.class);
startActivity(photoReviewIntent);
}
break;
case R.id.image_log:
Intent imageLogIntent = new Intent(this,ImageLogActivity.class);
startActivity(imageLogIntent);
break;
}
}
#Override
public void onPause(){
super.onPause();
mCamera.stopPreview();
mCamera.release();
}
#Override
public void onResume(){
super.onResume();
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
mCamera = getCameraInstance();
if (mCamera != null){
mPreviewScreen = new CameraPreview(this,mCamera);
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.camera_preview);
frameLayout.addView(mPreviewScreen);
}
else
Toast.makeText(this, R.string.failed_to_open_camera, Toast.LENGTH_LONG).show();
}
else
Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_LONG).show();
}
}
** preview screen java class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch (IOException e) {
Log.i("Error starting camera", e.getLocalizedMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.i("Error starting camera", e.getLocalizedMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Handeled in activity
}
}
In onResume(), an old mPreviewScreen may still exist, and cause problems. Consider adding the following to onPause():
if (mPreviewScreen != null) {
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.camera_preview);
frameLayout.removeView(mPreviewScreen);
mPreviewScreen = null;
}
mCamera = null;

Load camera inside custom ViewGroup

Im creating a custom ViewGroup using annotations lib.
I want to load the camera in a SurfaceView that is in my ViewGroup. The problem is that when i put my ViewGroup inside my Layout, the camera is not loaded (SurfaceHolder.Callbacks are not called).
Is there a way to put a Camera in my custom View?
My code works fine in an Activity, but in my View its not showing camera.
Thats my code:
#EViewGroup(R.layout.activity_custom_camera)
public class TakePictureView extends RelativeLayout implements SurfaceHolder.Callback {
Context context;
Activity activity;
boolean previewing = false;
Camera camera;
#ViewById(R.id.camerapreview)
SurfaceView surfaceView;
#ViewById(R.id.button_take_picture)
ImageView takepicture;
SurfaceHolder surfaceHolder;
LayoutInflater controlInflater = null;
Camera.PictureCallback jpegCallback;
public TakePictureView(Context context, Activity activity) {
super(context);
this.context = context;
this.activity = activity;
}
public TakePictureView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public void bind(){
activity.getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (surfaceHolder != null){
camera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
}
});
jpegCallback = new Camera.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(activity, "Picture Saved", Toast.LENGTH_SHORT).show();
}
};
takepicture.setClickable(true);
takepicture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
takePicture();
}
});
}
void takePicture(){
camera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(null, null, jpegCallback);
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d("CAMERA", "CRIADA");
camera = Camera.open();
Log.d("CAMERA", "CRIADA" + camera.getParameters().toString());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d("CAMERA", "SURFACE CHANGED");
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
Camera.Parameters parameters = camera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// For Android 2.2 and above
camera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
Hi Instead of extends the view group you should have to extends the SurfaceView & Use the custom class inside your activity and layout. see the below code, It will sure help you.
Packager com.test.cam;
public class AdvancePreview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mSurfaceHolder;
public Camera mCamera;
public Activity mActivity;
public AdvancePreview(Context context) {
super(context);
}
public AdvancePreview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setUpSurface(Activity activity){
try
{
mActivity = activity;
this.mSurfaceHolder = getHolder();
this.mSurfaceHolder.setFormat(PixelFormat.JPEG);
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
catch(Exceptions e){
e.printStackTrace();
}
}
private SurfaceHolder getSurfaceHolder(){
return this.mSurfaceHolder;
}
// SurfaceHolder.Callback
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.print(this.getClass().toString(), "surfaceCreated()");
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(getSurfaceHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
// SurfaceHolder.Callback
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Parameters params = null;
Log.print(this.getClass().toString(), "surfaceChanged()");
try {
if (camera != null) {
params = mCamera.getParameters();
params.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(params);
mCamera.startPreview();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// SurfaceHolder.Callback
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
mCamera.stopPreview();
mCamera.release();
} catch (Exception e) {
e.printStackTrace();
}
mCamera = null;
}
public void startTakePicture() {
Parameters params = null;
AudioManager mgr = null;
Log.debug(this.getClass().toString(), "startTakePictre()");
try {
mgr = (AudioManager)Const.CONTEXT.getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
if (mCamera != null){
params = mCamera.getParameters();
params.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(params);
mCamera.autoFocus(new CustomAutoFoucsCallback(activity));
}else{
activity.finish();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In next step how to use this AdvancePreview class in your activity, see the below code with activity and it layout xml file.
Packager com.test.cam;
public class CamActivity extends Activity {
public AdvancePreview mAdvancePreview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cam_activity);
mAdvancePreview = (AdvancePreview)findViewById(R.id.advancepreview);
mAdvancePreview.setUpSurface(this);
}
// class this function on click event of button
public void takePicture(){
mAdvancePreview.startTakePicture();
}
}
cam_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<com.test.cam.AdvancePreview
android:id="#+id/advancepreview"
android:layout_width="1dp"
android:layout_height="1dp"
/>
</LinearLayout>
For save the captured photo save use the CustomAutoFocusCallback see the below line from AdvancePreview
camera.autoFocus(new CustomAutoFoucsCallback(activity));
Let me know if you any question or query. Thank you

how to link face detector api with the photo activity

public class PhotoActivity extends Activity implements SurfaceHolder.Callback {
private ImageView imageView;
private SurfaceView mSurfaceView;
private Bitmap bmp;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private Parameters parameters;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
imageView = (ImageView) findViewById(R.id.image_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
parameters = mCamera.getParameters();
mCamera.setParameters(parameters);
mCamera.startPreview();
Camera.PictureCallback mCall = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
imageView.setImageBitmap(bmp);
mSurfaceView.setVisibility(View.INVISIBLE);
// Call web service
SendPhotoAsync photoToWeb = new SendPhotoAsync(data);
photoToWeb.execute();
}
};
mCamera.takePicture(null, null, mCall);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
how i could modify this code to detect face on camera preview,using face detector api in android.. any help please..
i also want to detect eyes then..hope someone can help me..i went through thiswhich works on button click.in my case for taking photo no button click is there..
someone with some productive code will be appreciable..please help me its very critical
if you have the android API for face detector..call this activity from the photo activity..in photo activity save the captured image to sd card...read this file in the face detector api..thus we can make it..but samsung galaxy+google nexus doesnt perform face detection..AAkash does..

Modify live camera view

How can I modify live camera view on Android?
I was searching and found this app https://play.google.com/store/apps/details?id=com.fingersoft.cartooncamera as good example what I want to do. I wanted to apply some effect to my camera view as well. I need to find a way to add some effects or draw something on my camera view.
As far as I understood I have to get some video stream, apply some changes and show back in camera view.
Any ideas?
Much thanks!
You can find more information about this topic Android - Camera Preview and in this post.
A completely other approach would be to use OpenCV.
The smallest piece of code I could think of to get an image and preview it on the screen looks like this:
public class MainActivity extends Activity implements Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder holder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
}
#Override
protected void onResume() {
super.onResume();
camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
holder = surfaceView.getHolder();
holder.addCallback(this);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
// You could apply some pixel operations directly here.
Log.d("Camera", "Camera image aquired");
}
});
}
#Override
protected void onPause() {
super.onPause();
camera.stopPreview();
camera.release();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
A full example that does this, can be found on GitHub.

Android onPictureTaken not being called

I'm trying to make a screen where the use will be able to take a photo. This photo will go to the database. The problem is, I've tried multiple approaches and in every approach, I need to use the PictureCallback. But the onPictureMethod from PictureCallback is never called, no matter what.
I already tried looking into this and this, but still can't move.
Edit: Using Android 2.2 (API 8)
EDITED CODE:
package touchcare.idealogix.android;
//imports
public class CameraActivityTest extends Activity implements SurfaceHolder.Callback
{
private SurfaceView surfaceCamera;
private SurfaceHolder holderCamera;
private Camera camera;
private Button btnCapture;
private PictureCallback mPictureJpg;
private PictureCallback mPictureRaw;
private ShutterCallback shutterCallback;
#Override public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContentView(R.layout.layout_camera);
Log.d("PICTURE", "ACTIVITY START");
surfaceCamera = (SurfaceView) findViewById(R.id.surfaceCamera);
btnCapture = (Button) findViewById(R.id.btnCapture);
holderCamera = surfaceCamera.getHolder();
holderCamera.addCallback(this);
holderCamera.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
shutterCallback = new ShutterCallback()
{
#Override
public void onShutter()
{
//DONOTHING
}
};
mPictureRaw = new PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
//DONOTHING
}
};
mPictureJpg = new PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
Log.d("PICTURE", "ON PICTURE TAKEN START");
Intent intent = getIntent();
final boolean beds = intent.getExtras().getBoolean(Main.BEDS, false);
final boolean nurse = intent.getExtras().getBoolean(Main.NURSE, false);
final int position = intent.getExtras().getInt(Main.POSITION, 0);
if(beds)
{
BedroomDataSource bedDs = new BedroomDataSource(CameraActivityTest.this);
String where = SQLiteBedroomHelper.COLUMN_UID + "=" + AppData.getBedrooms().get(position).getUid();
bedDs.open();
bedDs.updateBedroom(where, null, null, null, null, null, null, data);
bedDs.close();
Log.d("PICTURE", "BEDS BOOLEAN");
AppData.getBedrooms().get(position).setImage(data);
}else if(nurse)
{
}
Log.d("PICTURE", "ON PICTURE TAKEN END");
finish();
}
};
btnCapture.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View arg0)
{
camera.takePicture(shutterCallback, mPictureRaw, mPictureJpg);
}
});
}
#Override public void surfaceCreated(SurfaceHolder holder)
{
camera = Camera.open();
Camera.Parameters params = camera.getParameters();
params.setPreviewSize(holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
params.setPictureSize(32, 32);
params.setJpegQuality(100);
camera.setParameters(params);
try
{
camera.setPreviewDisplay(holder);
}catch(IOException ex){
Log.d("PICTURE", "PREVIEW EXCEPTION");
}
camera.startPreview();
Log.d("PICTURE", "SURFACE CREATED");
}
#Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
Log.d("PICTURE", "SURFACE CHANGED");
}
#Override public void surfaceDestroyed(SurfaceHolder holder)
{
camera.stopPreview();
camera.release();
Log.d("PICTURE", "SURFACE DESTROYED");
}
}
Thanks.
EDIT: Looks like that some photos are taken and the callback is reached. The database gets the photos, and loads back in bitmap just fine. But depending on what I'm taking a photo of, the callback isn't reaching. Smaller and simpler things are 100% chance the callback will be executed.
It looks like you create the callback mPicture, and then never set it as the callback for anything. I've never used any picture stuff, so I can't advise on where to set it, but as far as I know you need to register the callback for it to be called, just defining it won't do you any good.

Categories

Resources