I am taking a picture in Android (2.3 and greater) that takes a picture using camera.takePicture(). It works great, but I get weird behavior on different devices. On my Nexus One, the image I captured stays frozen for a few seconds before reverting to the preview. On my Transformer, it reverts to the preview almost immediately.
For now, a workaround would be to call camera.stopPreview() in the onShutter() event, but that's still a bit weird, since it's not showing the photo you took, it's showing what the preview saw a split second after you took the picture. On the Transformer, you can even see it "freeze-move-freeze" as it freezes for a split second after taking the picture, starts moving again, then gets to onShutter and freezes when I call stopPreview().
Does anyone know of a setting somewhere, or some code I could call, that would tell the camera how long to hold onto that image before restarting the preview? Or better yet, have it not automatically release the preview at all, and wait until I call startPreview?
on my devices I have to restart the preview manually, it doesn't start up itself after taking a picture. I use a picture callback like
camera.takePicture(null, null, takePictureCallback);
and the callback is
private Camera.PictureCallback takePictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera cam) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (camera != null) {
camera.startPreview();
}
canTakePicture = true;
}
}, PHOTO_PREVIEW_LENGTH);
new PhotoProcessor(activity, targetUri).execute(data);
}
};
PhotoProcessor saves the image, PHOTO_PREVIEW_LENGTH is the length in ms for how long is the captured image shown.
Related
I am developing an android application in which the camera preview is shown at all times. When the user wants, he can take a picture of that preview with the takePicture (), and apply different filters that picture.
The problem is that when I take a picture with takePicture () method, the picture freezes for a while and I want this freeze-frame remains as long as the user wants to apply the necessary filters, and when he wants, return to preview mode the camera immediately.
I am using the OpenCV library and specifically the JavaCameraView class to get the parameters of the camera and then take the pictures I want.
mCamera.takePicture(null,null,new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera myCamera) {
if(data != null){
bm = BitmapFactory.decodeByteArray(data, 0, data.length);
Log.i(TAG, "Caracteristicas de la foto: "+bm.getWidth()+"x"+bm.getHeight());
mCamera.startPreview();
}
}
};
In the onPictureTaken () method I store the image into a bitmap, and then to draw it on a canvas with the resolution of the camera. This will be done in CameraBridgeViewBase class.
Thank you in advance!
You can restart preview immediately from onPictureTaken() callback. The trick is that you put the ImageView that displays the captured image on top of the SurfaceView where you display live preview. Now, it's enough to imageView.setVisibility(View.GONE) and your preview will be immediately live.
In my Android app I want to take a photo. I have Samsung galaxy Gio (Android 2.3.3) and I was simply using camera.takePicture(null, null, Activity.this);, in my Activity I implemented PictureCallback method and everything was fine until I checked my app on Sony Xperia S (Android 4.0), on this phone the preview didn't freeze however it took a photo, so I add camera.stopPreview() function after taking a picture and now it was working fine on Xperia S but on my Samsung GIO after implementing this my screen after taking a photo goes black, does anyone have idea how to solve it ? Thanks for help
Here is my code:
When user clicks framelayout I use:
case R.id.camera_preview:
camera.takePicture(null, null, Activity.this);
break;
And in Activity i implemented picturecallback method:
public void onPictureTaken(byte[] data, Camera arg1) {
imageData = data;
cam_preview.stopPreview();
}
I'm not saving image immediately because I'm giving user choice to save or not to save a picture
From http://developer.android.com/reference/android/hardware/Camera.html#takePicture(android.hardware.Camera.ShutterCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback):
"Preview will be stopped after the image is taken; callers must call startPreview() again if they want to re-start preview or take more pictures."
So according to this the picture callback should be as follow:
public void onPictureTaken(byte[] data, Camera arg1) {
imageData = data;
cam_preview.startPreview();
}
I have an app in which the client uses the camera to take a picture. The preview of the image is being shown in the tablet using a SurfaceView, before the person hits my "click" button. When the person hits the click button, the method onPictureTaken is called, and, in that method, I save the image and also call the camera.stopPreview() method (so the user can see the picture that was taken).
There is an issue, however... If the user is moving around the tablet at the moment that the picture is taken, the still picture actually shown after the stopPreview method is called DOES NOT correspond to the one that I get in the byte array of the onPictureTaken method. There is a delay of some miliseconds there in which make that difference to stand out when the user is moving around the tablet just before the picture is taken (I know that 99% of the people will not move the tablet around while taken the picture, but my client actually noticed this issue and want it fixed...). I have tried to move the save operation to a separete thread, as shown below, so the onPictureTaken method can execute as fast as possible. Still, it had no effect at all...
private PictureCallback pictureCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
camera.stopPreview();
reference = data;
new PictureCallbackHeavy().execute();
}
};
I have also trield to call camera.stopPreview() just BEFORE I call the takePicture method (and not inside the onPictureTaken() method). But the result is the same.
What can I do to sync the stopPreview method so I can show EXACTLY the image that was taken and that is in the byte array of the onPictureTaken() callback?
Thank you in advance!! =)
Unfortunately you can't acquire a reasonable good preview image just by calling stopPreview() because between the moment the picture is taken and the moment onPictureTaken() is called there can pass quite some time because it works like this:
The camera actually takes the picture (that's what you want to preview)
onShutter() is called
onPictureTaken() for the raw image data is called (on some devices)
onPictureTaken() for a scaled preview image is called (on some devices)
onPictureTaken() for the final compressed image data is called (the one we are talking about here)
So you have to convert the byte[] data in your onPictureTaken() callback into a Bitmap and map that Bitmap onto an ImageView that you should position above your SurfaceView to show the still preview image.
The code will probably look something like this:
public void onPictureTaken(byte[] data, Camera camera) {
camera.stopPreview();
final Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
surfaceView.setVisibility(SurfaceView.GONE);
imageView.setVisibility(ImageView.VISIBLE);
imageView.setImageBitmap(image);
reference = data;
new PictureCallbackHeavy().execute();
}
I have some trouble with the onAutoFocus callback of the Android Camera API. In the constructor of my Preview class I set the focus mode to FOCUS_MODE_AUTO and the flash mode to FLASH_MODE_AUTO. The button I present to the user to take a picture has a custom animation attached to it. When the user pressed the button, the animation starts and so does the auto focus:
public void onAnimationStart(Animation animation) {
isAutoFocusing = true;
AutoFocusCallBackImpl autoFocusCallBack = new AutoFocusCallBackImpl();
camera.autoFocus(autoFocusCallBack);
}
Then in the onAutoFocus method I take the picture:
public void onAutoFocus(boolean success, Camera camera) {
if (camera != null) {
try {
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
} catch(Exception e) {
// If something went wrong, we return
// the user to the dashboard.
setResult(Constants.PICTURE_CAMERA_ERROR);
finish();
}
}
}
This works perfectly when there is enough light (so without the flash). In the dark however, the flash goes off and the picture is taken, but it appears that the camera did not focus properly. I know that the onAutoFocus callback is called immediately if auto focus isn't supported by the camera, but that clearly isn't the case here. Is auto focus impossible in the dark (even with the flash)?
This obviously is a hardware issue: To focus automatically, your device needs an image. No image (in the dark) -> no autofocus. There is no way for the camera to tell whether the image is sharp if there is no image, that's why focusing in the dark does not work.
That's why cameras (and I guess some android devices too) have a small light which gets switched on while focusing. But I guess most phones don't have this focus-light :/
We are using an LG Optimus speed and are trying to obtain an image from the camera with our own activity. The Code we are using to do so is:
GetImage(new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera) {
camera.startPreview();
bmp = BitmapConversion.convertBmp(data));
}
});
...
public static void GetImage(final PictureCallback jpgCallback) {
GetCamera().autoFocus(new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean success, Camera camera) {
if(success)
GetCamera().takePicture(null, null, jpgCallback);
else
GetImage(jpgCallback);
}
});
}
The images have a considerable worse quality than the images obatained with the native android camera app. Here are 2 example pictures, both taken with a resolution of 640x480 an magnified. As you can see the left picture taken with the native app looks "cleaner" than the right taken with our own application.
Any Ideas?
You don't know what the native app is doing in terms of configuring the camera before taking the image and post-processing after taking the image.
There are many settings available on the camera which are well documented and should be investigated.
You should also be aware that vastly different results exist on using the same method but with the slightest variation in light and focus.
Try looking into the autofocus settings and perhaps do something on autofocus callback.
When comparing the two methods make sure your camera is balanced on something rather than handheld and ensure that the distance and light levels are identical.