I have created a camera app and using the data to do something .But the data is always in landscape mode .
I have tried this which is making the preview in portrait mode but the byte[] I am getting still gives me a landscape photo.
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
I know I can make it as a bitmap and rotate it 90 but I need only the data from onPictureTaken.
I also tried
param.setRotation(90);
Which is not working on some of the devices.
You are right, this is how camera API works (unlike iOS). There are some efficient methods that can rotate the pixels to portrait if you really need this, but they never come at 0 cost. So the best practice is to adjust your code that processes the arriving preview frames.
I'm using Android + Opencv(new to opencv) and I'm currently working with real time object detection (the object stays really close to the android device Camera) , and I noticed that the Android camera's autoFocus keeps modifying my frames (kind of 'zoom in' and 'zoom out' effect) which make it harder for me to keep tracking the object.
I need to turn the "AUTO FOCUS" off because in my case the more blurred image input I have, the better, and I also need to turn the AutoWhiteBalance off as well, or maybe set to a different value.
I would like to know how to do it through my OpenCV CameraBridgeViewBase so I could modify the camera's Focus/WhiteBalance settings.
I've trying to find a way to solve it, and I noticed that many people face the same problems.
Here, at Stack Overflow, would be a great place to find someone who have worked with that and found a good way to overcome these problems.
create your own subclass of javacameraview
public class MyJavaCameraView extends JavaCameraView {
where you can have access to mCamera;
add whatever camera access using method you are interested in
for example
// Setup the camera
public void setFlashMode(boolean flashLightON) {
Camera camera = mCamera;
if (camera != null) {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
and use this new class as part of the main activity
//force java camera
mOpenCvCameraView = (MyJavaCameraView) findViewById(R.id.activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.enableView();
I am trying to create a custom camera app. I followed the Android Developer example from here with minor tweaks. However, my camera preview turns out to be rather dark. On the other hand, the stock camera gives a much brighter preview.
I have tried several settings to make it work better but it seems none of them are having any impact. Relevant code is posted here.
CameraActivity (Main)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
if(CameraHelper.checkCameraHardware(this)) {
mHelper = new CameraHelper(this, getWindowManager().getDefaultDisplay());
}
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(this, CameraHelper.camera);
mPreview.setLayoutParams(new LayoutParams(CameraHelper.mSize.width, CameraHelper.mSize.height, Gravity.CENTER));
preview.addView(mPreview);
}
CameraHelper class (initialize the camera and set the default parameters)
public CameraHelper(CameraListener listener, Display display){
mListener = listener;
camera = getCameraInstance();
mParameters = camera.getParameters();
initCameraParameters();
mSize = getPreviewSize(display);
mParameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
mParameters.setPictureSize(2560, 1920);
mParameters.setAutoExposureLock(false);
mParameters.setAutoWhiteBalanceLock(false);
mParameters.set("iso", "ISO800"); //Tried with 400, 800, 600 (values obtained from flatten())
mParameters.setColorEffect("none");
mParameters.setPictureSize(2560, 1920);
mParameters.setPreviewFrameRate(20);
mParameters.set("scene-mode", "auto");
mParameters.setFocusMode("auto");
mParameters.setExposureCompensation(4);
camera.setParameters(mParameters);
}
The Camera sends the frames to SurfaceHolder.Surface from the example linked from developer pages above.
See the difference here:
Stock Camera App
My Camera App
Tried setting the ISO, etc based on upack parameters from the camera as posted here. It still didn't work.
Parameters(16369):
effect-values=none,mono,negative,sepia,aqua,sharpen,purple,green-tint,blue-tint,pink,yellow,red-tint,mono,antique;exposure-compensation-step=0.5;focal-length=3.43;focus-areas=(0,0,0,0,0);focus-distances=0.10,1.20,Infinity;focus-mode-values=auto,macro,facedetect;gps-altitude=0;gps-latitude=0;gps-longitude=0;gps-processing-method=GPS;gps-timestamp=0;horizontal-view-angle=51.2;iso=auto;iso-values=auto,ISO50,ISO100,ISO200,ISO400,ISO800,ISO1600;jpeg-quality=1;jpeg-thumbnail-height=480;jpeg-thumbnail-size-values=640x480,0x0;jpeg-thumbnail-width=640;max-exposure-compensation=4;max-num-focus-areas=1;max-zoom=12;min-exposure-compensation=-4;picture-format=jpeg;picture-format-values=jpeg;picture-size-values=2560x1920,2560x1536,2048x1536,2048x1232,1600x1200,1600x960,800x480,640x480;preview-format=yuv420sp;preview-format-values=yuv420sp;preview-fps-range=15000,30000;preview-fps-range-values=(15000,30000);preview-frame-rate=30;preview-frame-rate-values=30;preview-size=640x480;preview-size-values=1280x720,800x480,720x480,640x480,352x288;rotation=0;scene-mode=auto;scene-mode-values=auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight,asd,backlight,dusk-dawn,text,fall-color;vertical-view-angle=39.4;video-frame-format=yuv422i-yuyv;whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;zoom=0;zoom-ratios=100,125,150,175,200,225,250,275,300,325,350,375,400;zoom-supported=true;focus-mode=auto;picture-size=2560x1920;exposure-compensation=4;
Edit: Upon further testing based on comments below, it appears that its just the preview that is turning out darker than it should be. The actual captured image is well lit and exposure compensatiion seems to be working fine. Its just the preview that is giving me a headache. Tested on i9003 running CM11 and Nexus 10 running stock android.
There appears to be a bug with certain cameras reporting the supported preview FPS range incorrectly. You can identify the offending devices by those that return the same value for min and max when calling
getPreviewFpsRange (int[] range)
In my case I saw this issue with devices that reported (15000, 15000) and (30000, 30000), but not with devices where the values were different, like (7000, 30000).
The best solution I could find was to identify the supported FPS range that had different values for min and max, and set that:
Camera.Parameters params = camera.getParameters();
final int[] previewFpsRange = new int[2];
params.getPreviewFpsRange(previewFpsRange);
if (previewFpsRange[0] == previewFpsRange[1]) {
final List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange();
for (int[] range : supportedFpsRanges) {
if (range[0] != range[1]) {
params.setPreviewFpsRange(range[0], range[1]);
break;
}
}
}
camera.setParameters(params);
This works because the ranges reported seem to only have 1 item with the actual range. Eg:
BLU Vivo XL:
preview-fps-range=30000,30000
preview-fps-range-values=(15000,15000),(20000,20000),(24000,24000),(5000,30000),(30000,30000)
Pixel:
preview-fps-range=7000,30000
preview-fps-range-values=(15000,15000),(24000,24000),(7000,30000),(30000,30000)
A more robust approach would be to set the min and max by comparing all those available.
In addition to the previous answers, this can happen with Camera2 if you are doing
createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
change to
createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
UPDATE: I have also begun to see a dark preview on some newer Pixel devices and this happens if you don't set the fps in the capture request or if you set the fps to something that the device can't handle BUT not on Samsung devices like the Note 10 and S10
From my experiments, scene-mode setting can change the preview (unlike ISO or exposure-compensation, which both work for captured pictures). Don't use auto. Try scene-mode-values=night or scene-mode=dusk-dawn.
The problem with scenes is that the supported values are not standardized across devices. But some kind of night is usually present.
In my current application, I've got a class holding an instance of a Camera object and trying to do the following:
1) Wait for a specified time, e.g. nothing (this is done via a TimerTask)
2) Request to focus via autoFocus
3) In autoFocus callback, request OneShotPreviewCallback
4) In preview callback, save image
5) Repeat
While the white balancing is working fine prior to the first autoFocus, it stops after the first focussing has been done. Well, of course I looked up the API, and there is one interesting statement in the autoFocus description.
But auto-focus routine may stop auto-exposure and auto-white balance transiently during focusing.
But it seems it is non stopped only transiently, but permantly. Funny enough, with the subsequent call of autoFocus, the camera tries to ajust the whitening again, but the correct value is mostly only with the second or third autoFocus.
I also tried to set the white balancing in code, but it didn't change anything.
setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
Does anyone else know this issue, or am I missing some point ? I know that I could permanently call autoFocus to force the white balancing, but that doesn't seem the optimal way for me, because prior to the first call auf autoFocus, it works perfectly fine.
P.S.: I'm testing on a Samsung Galaxy S2 with Android 4.0.3.
I have ran into similar issue on Samsung Galaxy 2 Duos 2. In this case, the auto exposure settings have stopped working instead of the WB. I tried to cycle (on/off) the auto exposure param and it worked for me.
mCamera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean b, Camera camera) {
Camera.Parameters params = camera.getParameters();
if (params.isAutoExposureLockSupported()) {
params.setAutoExposureLock(true);
camera.setParameters(params);
params = camera.getParameters();
params.setAutoExposureLock(false);
camera.setParameters(params);
}
}
});
I've got the similar problem on Samsung Galaxy Ace - after first autofocus, camera white balancing turns off and does not turn on again, no matter how much I do autofocus after.
As there are no API methods to tell camera to resume white balancing, and resetting the camera parameters in autofocus callback doesn't do the trick, my guess is that it is a bug in camera driver in Samsung phones - I've tried my application with different phones and only on this Samsung Galaxy Ace (GT-S5830; updated to Android 2.3.3), camera white balancing does not resume after autofocusing.
Maybe we should issue a bug ticket on developer.samsung.com?
It seems that
mCamera.stopPreview();
mCamera.startPreview();
in AutoFocusCallback can enable auto exposure again, but bringing a very short pause on the preview as side effect.
I am writing an app that sets the flash mode to torch. I have been testing the application on my Droid X, and the LED light does not come on. I tried it on a Droid Incredible and it worked fine. I can't figure out what the problem is. Here is part of my code for turning on torch mode.
Camera mCamera = Camera.open();
Camera.Parameters params = mCamera.getParameters();
if(params.getFlashMode() != null){
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
}
mCamera.setParameters(params);
I have added mCamera.startPreview(); because I read that should make a difference, but it doesn't. I also made a list of available flash modes and displayed them to the screen to make sure that my Droid X does have torch mode, and it was in the list. I even created a new application from code I found online that turns the LED flash on and off with a button. Again it worked fine on the Droid Incredible but not the Droid X. Is there something I am missing to get this to run on the Droid X, or could it be something with Gingerbread? The Droid X is running Gingerbread and the Droid Incredible is running FroYo.
There are quite a few quirks when setting FLASH_MODE_TORCH.
Often you need to start a camera preview:
Camera mCamera = Camera.open();
mCamera.startPreview();
Camera.Parameters params = mCamera.getParameters();
if(params.getFlashMode() != null){
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
}
mCamera.setParameters(params);
That may resolve it on some phones, other phones also require the preview to be drawn to a SurfaceView. This can be done by implementing SurfaceHolder.Callback interface in your activity.
See an example here.
It could be that the Droid X doesn't support Torch Mode. Try something like this:
List<String> pList = camera.getParameters().getSupportedFlashModes();
if (pList.contains(Parameters.FLASH_MODE_TORCH))
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
Refer to Issue 191453:
SurfaceTexture mDummy = new SurfaceTexture(1); // any int argument will do
camera.setPreviewTexture(mDummy);
camera.startPreview();
The only thing I found that works on the Droid X is the code presented by Siddhpura Amit part way down the page in this answer Use camera flashlight in Android. He checks the manufacturer and checks to see if it contains the string "motorola." If so, he has special code that can switch the camera Flash LED on or off. I can verify that it does work as I have a Motorola Droid X.