Correct implementation of Flash for Custom Camera - android

I have a custom Camera that works just fine,except for the implementation of flash that Iam using.I have tried using FLASH_MODE_AUTO in surfaceChanged.I have also tried using the following code using a Light Sensor:
SensorEventListener listener=new SensorEventListener(){
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//Not touching this with a ten foot pole
}
#Override
public void onSensorChanged(SensorEvent event) {
float lux=event.values[0];
Log.d(TAG, "The light sensor says: "+lux+" lux");
Camera.Parameters params=mCamera.getParameters();
cancelAutoFocus();
if(lux<50)
{
if(params.getFlashMode()!=Parameters.FLASH_MODE_ON)
params.setFlashMode(Parameters.FLASH_MODE_ON);
if(params.getExposureCompensation()!=params.getMinExposureCompensation())
params.setExposureCompensation(params.getMinExposureCompensation());
Log.d(TAG, "Exposure has been set to "+params.getMinExposureCompensation());
mCamera.setParameters(params);
}
else
{
params.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
}
}
};
Whatever I do,when I take a picture and the flash fires,my picture ends up looking like this:
However when I take a picture with the default Camera app,it looks ordinary,even a little dim.
I would like to get rid of this workaround using the Light Sensor entirely and use FLASH_MODE_AUTO.How can I get my camera to behave in low-light conditions and/or with the flash turned on?
Or is there any post-processing that I must do in order to ensure that the image is of lesser brightness.

Related

How to get device orientation whilst locking device in portrait

In my app I have set preferred orientations of portrait
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
])
But I would like to listen for changes in the orientation without changing what is displayed on the screen
I want to listen for orientation changes even though it is locked
I would like some code equivalent to this
MediaQuery.of(context).orientation
However, since I have locked it to portrait it will always say portrait
You can use SensorManager class for this:
SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(new SensorEventListener() {
int orientation=-1;;
#Override
public void onSensorChanged(SensorEvent event) {
if (event.values[1]<6.5 && event.values[1]>-6.5) {
if (orientation!=1) {
Log.d("Sensor", "Landscape");
}
orientation=1;
} else {
if (orientation!=0) {
Log.d("Sensor", "Portrait");
}
orientation=0;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
There are also other ways you can check in this post: Get phone orientation but fix screen orientation to portrait
I suggest using this package native_device_orientation it provides accurate orientation and doesn't just look at the devices width.
// Gets the devices orientation
NativeDeviceOrientation orientation = await NativeDeviceOrientationCommunicator().orientation(useSensor:true);

How to keep the flashlight on (programmatically) while the camera preview is ON

So for my Android app, I have created a SurfaceView and assigned it as camera preview and start camera preview using the necessary API's. But now I want to turn the Flashlight ON (kind of act like a Torch) while the preview is working.
Please note that I have seen tons of examples online on how to turn flashlight on and it works as long as I don't call the open camera API. Below is the code -
try
{
CameraManager cameraManager = (CameraManager)context.GetSystemService(Context.CameraService);
if (cameraManager != null)
{
//for the sake of brevity, hardcoded the camera id. 0 is mostly back camera
cameraManager.SetTorchMode(0, true);
}
}
catch (CameraAccessException e)
{
LogUtil.Error("CameraInput", e.ToString());
}
Please note I am testing on Android N and hence the above code works flawlessly. But as soon as I call below line of code, the flash turns off.
Camera camera = Camera.Open(0);
// ...... some code ....//
camera.StartPreview();
When the above 2 lines execute, the flash goes off. Is this a know behaviour like where camera takes exclusive lock over flash hardware and resets it's value to default.
I tried reversing the above code i.e calling the Camera Open API being called first and then setting the flash. On that I get CameraAccessException , camera already in use.
What am i missing ?
Try this while previewing on SurfaceView
params = camera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_ON);
camera.setParameters(params);
Remember that If you want to use it as flashlight you can do:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
If not, to turn flash on which will come out when you take the picture, you use:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
Happy Coding!
Figured out how to torch on and off while camera is previewing. On button click to on/off the light, use this code:
//at some other function where camera is initialised and start preview
//...
Camera camera = Camera.open();
camera.startPreview();
//...
boolean lightOn = false;
//...
buttonLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Camera.Parameters p = camera.getParameters();
if (!lightOn) {
lightOn = true;
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
} else {
lightOn = false;
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
}
}
});
Happy Coding! :D

How can i monitor the current FocalLength of android Camera

I have a SurfaceView that holds a Camera Preview. I have set the camera focus mode to: Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO
and added an AutoFocus callback. When i run the app, i can see the camera adjusting its' focus in real time, but the autoFocusCallback only ever gets fired once, and when it does, it always returns the same value. (2.95) regardless of how close or far i am from an in focus object.
Wondering what i am doing wrong.. is it even possible to get real time info on what the actual focal length is?
my SurfaceView, onSurfaceChanged code:
SurfaceHolder.Callback surfaceHolderListener = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
camera=Camera.open();
try {
camera.setPreviewDisplay(previewHolder);
camera.setDisplayOrientation(90);
}
catch (Throwable e){ }
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Parameters params = camera.getParameters();
Rect centralFocusArea = new Rect();
centralFocusArea.set(holder.getSurfaceFrame().width()/2-10, holder.getSurfaceFrame().height()/2-10, holder.getSurfaceFrame().width()/2+10, holder.getSurfaceFrame().height()/2+10);
ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
focusAreas.add(new Camera.Area(centralFocusArea, 1000));
//params.setPreviewSize(width, height);
params.setPictureFormat(PixelFormat.JPEG);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
// params.setFocusAreas(focusAreas);
camera.setParameters(params);
camera.startPreview();
camera.autoFocus(new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
Log.v("CAMERA", "FOCUS CHANGE:"+camera.getParameters().getFocalLength());
camera.getParameters().setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
});
}
public void surfaceDestroyed(SurfaceHolder arg0)
{
camera.stopPreview();
camera.release();
}
};
Maybe you are confusing two different concepts: focus distance and focal length.
It seems you are interested in the focus distance, i.e. the distance for which the optical system has perfect focus; this depends on how far or close you are from in focus objects.
On the contrary, the focal length is an intrinsic property of the optical system (i.e. of the camera lenses), and it is fixed in most standard mobile devices (optical zoom capabilities are needed to have a variable focal length).
The value you get, 2.95, is the focal length (in mm) of your camera. Nexus 7 2013 tablets have such focal length.
Thus, it is perfectly normal that the function getFocalLength() always gives you the same value.
Most Android implementations do not provide a proper value for the focus distance, despite the parameter being well-defined in the Android specification. Some time ago, I checked three different cameras, and none of them provided useful information.

Activation flash led cause freeze camera in android app

i have a little problem (or a big ^^), i've created a custom camera activity for an android app and when i try to activate the flash, the view is freezed :( , but when the activity is launched all is alright .
This is my way to activate the flash
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
FlashActivation.setVisibility(View.VISIBLE);
FlashActivation.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (inPreview) {
camera.stopPreview();
}
// NB: if you don't release the current camera before
// switching, you app will crash
camera.release();
camera = Camera.open(currentCameraId);
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_ON);
camera.setParameters(p);
camera.startPreview();
}
});
}
If some body can solved the problem it's with pleasure that i accept his solution :D.
Thank you
if you want to activate flash
There is no need to stop the preview and restart it.
And there is also no need to release the camera.
you can use this
Camera.Parameters parameters = camera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
camera.setParameters(parameters);

Extreme camera lag on Nexus 4

Using the following very simple camera preview activity (from a google example found here), the Nexus 4 camera is noticeably slower that the device's standard camera application:
public class LiveCameraActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;
private TextureView mTextureView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
setContentView(mTextureView);
}
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
} catch (IOException ioe) {
// Something bad happened
}
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.stopPreview();
mCamera.release();
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
}
}
I have been having issues with my application's camera speed on the Nexus 4, but I see this problem on no other devices. I was concerned that this was a Jelly Bean 4.2 difference, but Galaxy Nexus phones running JB4.2 work as normal with no lag. I realize this example code uses a TextureView, but other phones do not experience lag with this example.
Any help would be greatly appreciated.
I have found that the preview frame rate can be increased to a normal rate by setting the recording hint to true, but this severely decreases camera performance especially in medium to low light situations with regard to color saturation and contrast (I am shocked at the quality of the front facing camera given that this is Google's latest and greatest attempt to compete with the iPhone 5 and her quality cameras... can't wait for the X Phone).
This is not a solution to the problem, but it is something of a band-aid for developers looking to avoid shocking frame rates.
If you set the picture-size to 3264x2448, this will fix it. Even if you don't ever take a picture the picture-size is important because ZSL is enabled by default. The default picture size is 640x480 and this causes the slow preview frame rate. Disabling ZSL makes the preview even faster which is why setting the recording hit to true helps, enabling HDR does the same thing.

Categories

Resources