-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Camera preview is very dark on API23. (maybe only on LG G3) #53
Comments
I am experiencing the same issue on Sony Z5 (android 6) |
I did not manage to find a good solution. For now I stopped trying. |
The above had no effect for me, but this did: |
Google, any proper workaround for this issue? There are many questions on stackoverflow regarding dark preview using this demo. There is no any best solution for this. It would be great if you can suggest to fix this issue. |
Experiencing this on OnePlus 3 API 25, worked fine on my Note 4 running older API version. Neither of the above solutions worked for me. |
I am experiencing the same issue on Xiaomi 6 (android 7.1.1) |
This is frustrating because I know the cause of this bug, but I don't know of an adequate solution that's easy to implement. The problem is that for some reason the surface that's displaying the captured preview frames is acting as if the colors need to be converted from 'tv' ranges to 'full' ranges. This might be because the frames are captured in a YUV format. Some background: TV signals (which also use YUV, or in the US often YIQ which is similar) need to have some room for the signals to go too high or too low, for various reasons. Thus, for the Y channel the range is 16-235 instead of from 0-255, and for the U and V channels the range is 16-240 (again instead of 0-255). Most YUV signals are encoded this way, such as mp4 files and so on... But jpeg (and motion jpeg) are not encoded this way - instead using 0-255 for all channels. Overall it depends on what the hardware reports. Now, how do I know this is the fault of the surface view? Because in the 'Shader Editor' app, I can rescale the color values from the camera and fix them. And yes, it pulls values out from being negative... Which means that the values are being sent to the texture correctly, but the surface is rescaling and displaying the colors incorrectly. After some Googling, it seems that some people are reporting some devices as exhibiting this behavior and other devices as being fine. I've tonight just spent the last hour or two trying to find somewhere to set whether to use 'tv' or 'pc' (or sometimes known as 'limited' vs. 'full') ranges for the preview surface, and haven't found anything. It really doesn't help that 'limited' and 'full' are both the technical terms for this setting, and what Android uses to distinguish levels of support for the Camera2 API. Terrible naming conflict in my opinion. Basically... The 'fix' is to write some GLSL code that rescales the values. Woo :/ |
As a followup to the late night rant I typed up last night, I figured you might appreciate the GLSL code I've found works best. I used to just directly rescale the RGB values, but the colors remained sliightly 'off'. I've since found that the best way to do it seems to be converting into YUV first, rescaling, and finally converting back into RGB. Here's the code, at least for Shader Editor: #version 300 es
#extension GL_OES_EGL_image_external_essl3: require
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
// Tell Shader Editor to provide a texture for the back camera
uniform vec2 resolution;
uniform vec2 cameraAddent;
uniform mat2 cameraOrientation;
uniform samplerExternalOES cameraBack;
// For consistency with previous versions of GLSL ES
out vec4 gl_FragColor;
// YUV matrix for BT.601
const mat3 BT601 = mat3(
0.299, -299.0/1772.0, 0.5,
0.587, -587.0/1772.0, -587.0/1402.0,
0.114, 0.5, -57.0/701.0
);
void main(void) {
vec3 color;
vec2 texCoord = gl_FragCoord.xy/resolution;
// Orient the camera texture correctly
texCoord = texCoord*cameraOrientation;
texCoord += cameraAddent;
color = texture(cameraBack, texCoord).rgb;
// Fix incorrect scaling of YUV values by Android
color = BT601*color;
color.rgb *= vec3(219.0/255.0, vec2(224.0/255.0));
color.r += 16.0/255.0;
color = inverse(BT601)*color;
// Old color correction (doesn't use YUV)
//color = color*73.0/85.0 + 16.0/255.0;
gl_FragColor = vec4(color, 1);
} For devices not supporting OpenGL ES 3.0 and up, you have to provide a pre-computed inverse matrix (and change a few other minor tidbits): #ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
// Tell Shader Editor to use the back camera
uniform vec2 resolution;
uniform vec2 cameraAddent;
uniform mat2 cameraOrientation;
uniform samplerExternalOES cameraBack;
// YUV matrix for BT.601
const mat3 BT601 = mat3(
0.299, -299.0/1772.0, 0.5,
0.587, -587.0/1772.0, -587.0/1402.0,
0.114, 0.5, -57.0/701.0
);
// Inverse of the YUV matrix for BT.601
const mat3 BT601_INV = mat3(
1, 1, 1,
0, -25251.0/73375.0, 1.772,
1.402, -209599.0/293500.0, 0
);
void main(void) {
vec3 color;
vec2 texCoord = gl_FragCoord.xy/resolution;
// Orient the camera texture correctly
texCoord = texCoord*cameraOrientation;
texCoord += cameraAddent;
color = texture2D(cameraBack, texCoord).rgb;
// Fix incorrect scaling of YUV values by Android
color = BT601*color;
color.rgb *= vec3(219.0/255.0, vec2(224.0/255.0));
color.r += 16.0/255.0;
color = BT601_INV*color;
// Old color correction (doesn't use YUV)
//color = color*73.0/85.0 + 16.0/255.0;
gl_FragColor = vec4(color, 1);
} It's honestly probably much more efficient to use a pre-converted inverse matrix anyway, so you might want to use it even in OpenGL ES 3.0+. I don't because I kinda like having as few things defined as possible, and instead deriving everything from a minimal set of data. But that's just me. The matrices I provide here should be as accurate as possible, as I derived them myself with a calculator application (Qalculate) that lets me see the results as fractions. It may not be a 'minimal set of data', but it's more accurate than any rounding one could do! I use BT.601 because it's what the JPEG standard specifies, and because And by the way, before anyone says anything, yes I understand the difference between YUV and YCbCr. Yes I know I'm talking almost exclusively about YCbCr in these posts. However, YUV is the most useful thing to call it in this context, since YCbCr is essentially the digital version of YUV, and most people - when talking about software colorspaces - call it YUV - including Just figured I'd get that out of the way in case anyone felt like correcting me :) |
Experiencing this on Meizu PRO 6s API 25,and setting CONTROL_AE_EXPOSURE_COMPENSATION doesn't work for me. |
Does any one found some solution for this? It is really very pain full. |
I guess configuration of FPS can help.
And add this config to builders:
|
I can confirm that @Djek-grif solution works. |
i have same isuue and was solve that to other device with this method from stackoverflow and this method for getrange()
this work for any device , but i get complaint from client if this method not work in some device "Sony" but not all sony device. please give me some action if you have news idea for solve this issue. thanks and if i use @Djek-grif your merhod that make Brignest but camera show low quality |
The issue happens for some devices that use as the default FPS range a value where the lower and upper FPS bounds are the same, which limits how the AE algorithm can adjust to light changes. In addition, some devices seem to report the FPS ranges in a 1000 scale, which needs to be normalized. This is my current solution. It seeks an FPS range between 0 and 30 (you can change these constants), picking up the range with the widest spread between the lower and upper bounds, and also taking care of normalizing 1000 ranges. Please add any modifications you think it may need to improve it. Take into account that this method is only meant for photos, as for videos it makes sense to have an FPS range with equal lower and upper bounds.
|
same as my testing |
Same issue on Asus Zenfone 3 and Asus Zenfone 5. Setting up FPS range not helping at all. |
This sample has been migrated to a new location where we can accept Pull Requests (check README for more information). As recommended by GitHub, we are closing all issues and pull requests now that this older repo will be archived. If you still see this issue in the updated repo, please reopen the issue/PR there. Thank you! |
It works fine on my nexus 4, but on lg g3 it is very dark and quite unusable.
Here is my stack oveflow description.
http://stackoverflow.com/questions/38493000/android-camera2basic-app-has-very-dark-preview-in-android-6-0-lgg3
The text was updated successfully, but these errors were encountered: