I have written a camera app in android and I have tested it on two android phones, on one phone the auto-exposure works well when previewing but on the other phone it doesn't work at all. The first phone only works when I call the autoFocus() method. On the latter phone, the build-in app's auto-exposure works but not my code. Is there any method that can start use the auto-exposure manually?
Check Camera class
Camera.Parameters getParameters()
and check these two methods in Camera.Parameters class
int getExposureCompensation()
Gets the current exposure compensation index.
float getExposureCompensationStep()
Gets the exposure compensation step.
You should check the capabilities of camera of the phone before assuming existence of certain function
Related
I am working on an app where I have a camera preview and I take pictures in dark settings. Therefore, I need a way to manually control the exposure time of the camera and the settings of shutter speed, aperture, and iso.
I know it must be possible because the application Long Exposure Camera 2 (by AAASDream) has a way to manually change the exposure time and it works perfectly. I am not referring to the exposurecompensation which I already tried but was not sufficient enough.
Based off of this post, I tried setting
Camera.Parameters params = camera1.getParameters();
params.set("mode", "m");
params.set("aperture", 80);
params.set("shutter-speed", 9);
params.set("iso", 1600);
But this did not work at all.
Is there any hidden API or setting that I can use or any third party library I can use to accomplish this.
All help is appreciated, thanks.
I think there is no way to manually set the above mentioned values in android.hardware.camera. But it looks like the new version android.hardware.camera2 supports those functionalities.
Yes, it isn't possible to manually set one of the two mentioned parameters directly via the Camera 1 API. Neither the characteristics can be queried via a standardized method, because it isn't supported.
Of course there is a way around, to query or to set such properties via special methods, as relime9 currently mentioned:
// query all the settings you camera support (API 1)
mCamera.getParameters().flatten();
// set parameters - e.g. aperture
mCamera.getParameters().set("aperture", "80");
Additionally the specific device must support such a setting, which vary from device to device. On some devices there can be set certain values and with other you can't and can only use the ''auto'' mode.
For this reason they developed the Camera 2 API, which is more standardized and supports such functionalities.
i am trying to change camera2 basic example so camera starts showing preview on FACING_FRONT, but in that case snapshot stops working.
Here is a link to the example:
https://github.com/pinguo-yuyidong/Camera2/blob/master/camera2/src/main/java/us/yydcdut/camera2
I am sure, that besides cameraId change i need a lot more additional changes, but i couldn't find what else.
Many front-facing cameras are fixed-focus, so autofocus (AF) state remains INACTIVE, and the AF trigger does nothing.
You need to check if the camera actually supports focusing, and if not, don't use the AF trigger or wait for AF state to change.
To check if the camera supports focusing, look at http://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INFO_MINIMUM_FOCUS_DISTANCE
In API level 9, Android added the CameraInfo class, which includes information on each physical camera in the device. In particular, it includes an orientation attribute, which is "the angle that the camera image needs to be rotated clockwise so it shows correctly on the display in its natural orientation." This is distinct from the actual rotation of the device, which is found from getContext().getWindowManager().getDefaultDisplay().getRotation().
Android's sample code subtracts the rotation of the device from the orientation of the camera for rear-facing cameras (it's slightly more complicated for front-facing ones), and rotates the camera preview by this amount. This allows the preview to display properly in both portrait and landscape orientations of the screen.
How can I get the intrinsic orientation of the camera in API levels less than 9, where there is no CameraInfo class?
There is some platform specific solutions. But there is no easy general solution.
Android has a Hardware Abstract Layer(HAL), different vendors will implement the HAL differently. For example, different camera device may have different drivers, so they have different ways to get their data out, including your cameraInfo. When Android adds an API into the HAL, it requires its vendors to implement that API based on their hardwares. Then the Android framework and Android application can use that feature in a uniform way.
However, as you said, the getCameraInfo is not in the HAL Before Froyo. So a straightforward approach would be get those info from the driver or platform-specific library yourself.
For MSM Camera, there is a mm_camera_get_camera_info function in liboemcamera.so. You can use it to get a list of camera_info_t structs.
typedef struct {
int modes_supported;
int8_t camera_id;
cam_position_t position;
uint32_t sensor_mount_angle;
}camera_info_t;
The function encapsulates the actual system call to the target camera device. ioctl(controlfd, MSM_CAM_IOCTL_GET_CAMERA_INFO, &cameraInfo). You may directly call it if you like.
So unfortunately, you need to get that info based on the device you are working on. But may be you are expecting a general approach. Then I think the only way to achieve this is to implement the HAL yourself. Many if-else to decide which device or which ioctl command you need to use. Good luck man.
I'm writing a camera application that requires the same exposure regardless of ambient light. Unfortunately, setExposureCompensation() only acts like an offset. Can I turn off this auto adjustment, or is this more of a pre-user hardware correction?
EDIT: So, for Android 4.0 and above, there is a setAutoExposureLock(boolean) that should work for what you need. It doesn't let you set the exposure yourself, but after the exposure is determined, you can lock it into its current exposure. You need to guard it with a check for isAutoExposureLockSupported(), though, to make sure the device supports that feature.
To get the same actual exposure every time, you'd need to be able to set a fixed ISO, shutter speed, and aperture. As you said, the exposure compensation only offsets from the metered exposure, which the camera determines automatically. To my knowledge, there's no built in way to set the ISO, the shutter speed, or the aperture values in Android.
You should browse all your camera parameters to see if there are any related to ISO,shutter speed, and aperture.
Example:
Camera.Parameters params = mCamera.getParameters();
String sParams = params.flatten();
Log.d("TAG", "camera flatten: "+sParams);
I'm using this camera code to ask the camera to rotate the captured image data:
Camera.Parameters params = camera.getParameters();
params.set("rotation", 90);
camera.setParameters(params);
this seems to work on all phones, except the Droid. Has anyone else seen this? The image data is always landscape, however, the native camera app on the Droid produces portrait images ok.
I wonder if the Droid will only respect the new Camera.Parameters.setRotation() method, but this seems to only be available in API level 5?
setRotation also didn't seem to work for me on Nexus One, but I did get image rotation to work by following the example of the android Camera app itself.
The source code is available here:
https://android.googlesource.com/platform/packages/apps/Camera
Start with the Camera.java, but you'll also be looking at ImageManager.java, Util.java, and other files.
The basic idea is, you listen for orientation changes and capture what the orientation is at the time you snapped the picture. Then, when you get the picture bytes in the callback, you manipulate the bitmap, doing a rotation on the bitmap. Then convert the rotated bitmap back to jpeg. When you are done, you'll have had to copy a shocking amount of code from the camera app just for this rotation.
The rotation may just be stored in the jpeg exif header as explained in the setRotation document. On Droid that is actually the case. You can use jpeg header reading tools like jhead to verify this. You can also use the ExifInterface API to read the orientation tag in your program.
The Droid runs Android 2.0 (well, now 2.0.1) which are API levels 5 and 6, respectively.
So it's quite possible that the Droid only respects the (more sensible) 2.0+ API for rotation.
However, I guess your concern is compatibility across a range of device types and OS versions, so I imagine you would have to invoke the 2.0+ API via reflection after detecting the OS version (using android.os.Build.VERSION_CODES).