Android camera preview is dark

10,886

Solution 1

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.

Solution 2

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.

Solution 3

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

Share:
10,886
Puneet
Author by

Puneet

Updated on June 03, 2022

Comments

  • Puneet
    Puneet about 2 years

    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 Stock Camera Preview My 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.

  • Praveena
    Praveena over 9 years
    I have tested this on Nexus 7(Android L) and front camera works fine but back camera showing dark preview. I tried setting night mode but no use. I tried other popular camera apps and I found out that even they failed doing it. Only camera working fine is google camera. Is there anything to do with color effects?
  • Alex Cohn
    Alex Cohn over 9 years
    @Praveen: I have not done reverse engineering on the GoogleCamera, but judging from its requirements (4.4 and higher) and extra attention to Nexus devices, I may suppose that they tuned it to the less-than-wonderful back camera on Nexus 7.
  • slott
    slott over 9 years
    Scene modes like night or party will activate the camera - this is the case for Nexus 5 at least. What I did was to measure the light and then gradually change the exposure value based on that. This resulted in a nice result.
  • Praveena
    Praveena over 9 years
    @AlexCohn Thanks for your reply. Somehow I think that it is mandatory to use Camera2 api's rather than deprecated Camera apis. Just now I worked on Camera2 api's on my Nexus 7 and surprisingle evrything works fine. But only problem I have is, my app has lot of customization and it is too much work to port into Camera2..
  • Alex Cohn
    Alex Cohn over 9 years
    @Praveen: thanks for this info. It is not very surprising that Camera2 works better on Nexus 7(Androoid L) than the deprecated API. Me wonders, if the older ROM would behave same way. Unfortunately, I have encountered 4.4+ stock ROMs without Camera2 support (inspite of this being mandatory), and it will take a while until the old API will phase out business-wise.
  • Alex Cohn
    Alex Cohn over 9 years
    This could easily be the issue with the original problem: as I noted in a comment, the code there set FPS=20 while the camera reported support for range (15-30) fps.
  • Praveena
    Praveena over 9 years
    In my nexus 7 I can change the scene mode but not able to show color effects in preview even though taken picture gets effects.. I can see color effects for fraction of second while pressing shutter button. I tried all combination of FPS range but no use. Any idea?
  • Puneet
    Puneet over 9 years
    Sorry for a late reply. I sort of stopped following the issue after a month of no solution (was a trial project anyway). Unfortunately, setting scenes manually did not solve the problem.
  • Puneet
    Puneet over 9 years
    Let me try the FPS tweak(correction) and get back to you on this. I did try a lot of settings so I am keeping my fingers crossed.
  • Alex Cohn
    Alex Cohn over 9 years
    @Praveen: no, I don't know why color effects do not stick. I don't have a Nexus 7 device here to check.
  • Viish
    Viish over 6 years
    Thanks a lot, it fixes the issue on a lot of devices for us as well !
  • Vlad
    Vlad about 6 years
    This fixed it for me. But I wonder what i'm losing with this template (probably video quality)
  • prex
    prex over 4 years
    Works for me too and have same concern as @Vlad
  • Machine Tribe
    Machine Tribe about 4 years
    You should be using the 'CameraDevice.TEMPLATE_PREVIEW' while you are in a preview state. Then, once you are ready to record, you switch to 'TEMPLATE_RECORD' for your capture request.
  • Tomero Indonesia
    Tomero Indonesia almost 4 years
    so any solution for this?
  • Alex Cohn
    Alex Cohn almost 4 years
    @TomeroIndonesia this requires delicate device-dependent tuning. The other answers here seem to improve situation on some devices.
  • anonymous-one
    anonymous-one about 3 years
    Kindle Fire HD 2018 running Android 9.0. This fixed it for me. Thanks!