I am writing an application which uses the camera to take pictures and send them to a server.
When I gave the app to someone with a Nexus 5, it appears that the pictures come out too bright.
It might be an issue with the white balance or auto exposure. However, this does not occur when taking a picture with the stock camera app.
This issue does not reproduce on Nexus 4 and Samsung Galaxy S3.
This is the relevant code.
Taking a picture
Code:
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean b, Camera camera) {
setButtonToDefault();
mCamera.takePicture(shutterCallback, null, pictureHandler);
}
});
Camera initalization:
Code:
Camera.Parameters params = c.getParameters();
params.setFlashMode(params.FLASH_MODE_ON);
Log.i(TAG, "Autowhitebalance: " + params.getAutoWhiteBalanceLock());
Log.i(TAG, "Autoexposure: " + params.getAutoExposureLock());
Log.i(TAG, "iso: " + params.get("iso"));
Log.i(TAG, "params: " + params.flatten());
Log.i(TAG, "getExposureCompensation " + params.getExposureCompensation());
if (PhoneUtils.getDeviceName().toLowerCase().contains("GT-I9300".toLowerCase())) {
params.setFocusMode(params.FOCUS_MODE_FIXED);
}
c.setParameters(params);
Also, the iso param is not available on Nexus 5.
Has anyone else encountered this issue? Or has an idea on how to further investigate/resolve this issue?
Thanks
Related
A long time ago I wrote some code to work as a timer app for the camera on the Himalaya. I've had a couple of emails about this recently so thought I would post the important parts of code for firing off the camera here. Before it's lost forever as I have a Magician these days.
First I start the camera app:-
Code:
void CCameraTimerDlg::RunCameraApp()
{
// setup parameters for ShellExecuteEx
SHELLEXECUTEINFO sei;
memset(&sei,0,sizeof(SHELLEXECUTEINFO));
sei.cbSize=sizeof(SHELLEXECUTEINFO);
sei.hwnd=::GetDesktopWindow();
sei.lpFile=TEXT("\\Windows\\Camera.exe");
sei.nShow=SW_SHOW;
// start the camera app running (or if it's already running switch to it)
ShellExecuteEx(&sei);
}
Then get a handle to it's command window and take the photo:-
Code:
void CCameraTimerDlg::TakePicture()
{
// Find main Camera App window
HWND hCameraApp=::FindWindow(TEXT("WCE_IA_Camera_Main"),NULL);
// if we found it okay....
if (hCameraApp)
{
// find the Camera App's first child window (it's UI)
HWND hCameraSkin=::GetWindow(hCameraApp,GW_CHILD);
// if we found it okay ...
if (hCameraSkin)
{
// press the "take photo" button
::SendMessage(hCameraSkin,WM_COMMAND,0xBC4,0x00);
// wait while photo is taken
::Sleep(500);
// press "save photo" button
::SendMessage(hCameraSkin,WM_COMMAND,0xBD4,0x00);
}
}
}
and then quit the camera app
Code:
void CCameraTimerDlg::ExitCameraApp()
{
// find the Camera App's main window
HWND hCameraApp=::FindWindow(TEXT("WCE_IA_Camera_Main"),NULL);
// if we found it okay, ask it to close
if (hCameraApp)
::SendMessage(hCameraApp,WM_CLOSE,0,0);
}
I'm currently developing an app and from within the app I'd like to let the user select custom images to use.
Right now I use
Code:
public final int GOT_IMAGE =1;
private void getImage() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
mUri = Uri.fromFile(new
File(Environment.getExternalStorageDirectory(),"temp_image" +
".jpg"));
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent,GOT_IMAGE );
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (resultCode != RESULT_OK) {
customImgChk.setChecked(false);
return;
}
if (requestCode == GOT_IMAGE) {
Bitmap image = BitmapFactory.decodeFile(mUri.getPath());
if (image!=null)
{
image = WPUtil.resizeBitmap(image, WPUtil.IMAGE_SIZE_X,
WPUtil.IMAGE_SIZE_Y);
}
else
{
customImgChk.setChecked(false);
Toast.makeText(this.getApplicationContext(), "Failed to grab
image!", Toast.LENGTH_LONG).show();
}
}
}
This works great on a few devices but not all. I'd really like to come up with a universal way to perform this function but I have not found a way to do it yet.
I've thought about writing up my own image selector and cropper but I'd rather not re-invent the wheel.
Can anybody suggest a decent app/library that I can use to select and or crop photos from within my app?
ImageJ is great. It is a stand alone app but there are published apis for integrating into your own apps.
*its better than that, its open source and you can use the jar and just ignore the gui library
Might look into that
http://rsbweb.nih.gov/ij/
From something awesome
Hi,
im playing around with the Camera Service. The preview mode works well, but if I take a picture and save it, it is a lot darker as in the preview. I tried it with the delivered camera app and there is no such problem.
I tried it with many diffrent values (iso, brightness, scenemode, whitebalance), but nothing changed, but the preview. It seems, that the preferences only have effect in the previewmode.
Device: altek A14 leo
OS: Android 2.1
Picture saved by the standard camera app:
abload.de/img/stdapp8uql.jpg
Preview mode:
abload.de/img/previewrne6.jpg
Picture saved by my app:
abload.de/img/myappiugc.jpg
parameters of the camera
Code:
atk-frame=0
brightness-max=12
brightness-min=0
brightness=6
camera-id=1
contrast-max=2
contrast-min=0
contrast=1
effect-values=none,mono,sepia,whiteboard
effect=none
flash-mode-values=off,auto,on,red-eye
flash-mode=off
focus-mode-values=auto,infinity
focus-mode=auto
gps-altitude=0
gps-latitude=0.0
gps-longitude=0.0
gps-timestamp=1199145600
iso-values=auto,80,100,200,400,800,1600,3200
iso=auto
jpeg-quality=100
jpeg-thumbnail-height=384
jpeg-thumbnail-quality=100
jpeg-thumbnail-width=512
max-zoom=9
metering-values=spot,center,matrix
metering=center
min-zoom=0
orientation=landscape
picture-format-values=jpeg
picture-format=jpeg
picture-size-values=2048x1536,1280x960
picture-size=2048x1536
preview-format-values=yuv420sp
preview-format=yuv420sp
preview-frame-rate-values=15
preview-frame-rate=15
preview-size-values=640x480
preview-size=640x480
rotation=0
saturation-max=0
saturation-min=2
saturation=1
scene-mode-values=auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,candlelight
scene-mode=auto
SD9-poweron-mode=0
sharpness-max=2
sharpness-min=0
sharpness=1
smooth-zoom-supported=true
whitebalance-values=auto,fluorescent,daylight,cloudy-daylight
whitebalance=auto
zoom-factors=100,130,160,190,220,250,280,310,340,360,400
zoom-supported=true
zoom=0
Code:
private OnClickListener cameraClickListener = new OnClickListener() {
public void onClick(View v) {
inPreview = false;
cam.takePicture(null, null, photoCallback);
}
};
PictureCallback photoCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SavePhotoTask().execute(data);
startPreview();
}
};
class SavePhotoTask extends AsyncTask<byte[], String, String> {
protected String doInBackground(byte[]... imageData) {
File photo = new File(Environment.getExternalStorageDirectory(), "photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(imageData[0]);
fos.close();
Log.i("IMAGE SAVED ASYNC", photo.getPath());
} catch (java.io.IOException e) {
Log.e("Error", "Exception in photoCallback", e);
}
return (null);
}
}
Does anybody have an idea, what causes this behaviour?
thanks.
rgds
I am not sure what happening with you. But as far as your codes it should work well. try other camera apps. Like 360. But problem persist then go to service center. The problem is with hardware.
Hi,
sorry for the late response. It was no hardware issue. I just had to call autoFocus and takePicture in the AutoFocusCallback.
Code:
private OnClickListener cameraClickListener = new OnClickListener() {
public void onClick(View v) {
if (!isFocusing) {
isFocusing = true;
cam.autoFocus(autoFocusCallback);
}
}
};
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
isFocusing = false;
camera.takePicture(null, null, photoCallback);
}
}
};
regards
Hello. New here and I hope this post is okay. The "Is this a question?" checkbox says it not the QA forum but it is?
Working on an app that all it's supposed to do is repeat taking a picture every 5 seconds after pressing a button. Now, I've looked at handler, timer, etc but I can't figure out the right way to do it. This is the code currently, and the onCameraClick of course runs when the button on the screen is pressed. I want that button to activate some kind of repeater so the picture gets taken every 5000ms.
Code:
public class CameraImage extends Activity {
public static int cameraID = 0;
public static ImageView image;
[user=439709]@override[/user]
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameraimage);
image = (ImageView) findViewById(R.id.imgView);
}
public void onCameraClick(View v)
{
cameraID = 1;
Intent i = new Intent(CameraImage.this, CameraView.class);
startActivityForResult(i, 9999);
}
}
Now, this is something I'd definitely like to use but I'm not sure how to implement this correctly into the code above. Been trying trial and error for past few hours and nothing. Tried out a timer example someone put on another website, 10792454/image-capture-in-android-automatically but not much there.
At the same time however though, I'm not sure if the code should go in the other class with all the functions to run the camera. Any suggestions/tip or help I'd greatly appreciate it.
Try a loop. I'm not sure if you have tried this or if it will work with launching an activity, but it sounds like that is what you want to do. I don't know how you determine when to stop taking pictures but you can use a "for loop" or a "while loop".
example "for loop":
Code:
for (int i; i > someNumber; i++){
//Your code here
}
someNumber would be perhaps the number of pictures you want to take and you can use i to number each picture.
example "while loop":
Code:
Boolean buttonClick = false;
onCreate(){
OnButtonClick(){
OnClick(){
if(buttonClick == true){
buttonClick = false;
}else{
buttonClick = true;
}
onCameraStart(buttonClick);
}
public void onCameraStart(boolean runCamera){
while (runCamera == true){
//Your code here
}
}
This example I showed you how you would be able to start the camera on the first click and stop it when clicked again. The OnButtonClick would be the OnClickListener for your button.
Both these examples may need a little refinement but this should point you in the right direction. Hope this helps. You can put these in threads and pause the thread at the end of the loop for 5 secs so it will wait (I think).
It's simple use a timer and invoke it on first click
Sent from my GT-S5302 using Tapatalk 2
Just started using the Camera2 framework because of the increased control it provides over the low-level functions of the camera. However, I am having some trouble turning the flashlight on and off quickly. With the old Camera API, I could toggle flash while supplying a preview by:
Code:
try
{
android.hardware.Camera.Parameters parameters = c.getParameters();
if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF))
{
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
Log.i("HeartBeatAlgorithm", "LightOn");
}
else if (parameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_TORCH))
{
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
Log.i("HeartBeatAlgorithm", "LightOff");
}
c.setParameters(parameters);
}
catch (Exception exception)
{
c.release();
c = null;
}
And the flashlight would quickly turn on or off, without any noticeable interrupt. With Camera2, however, it seems as though flash mode is a property of the CaptureSession, meaning an entirely new CaptureSession needs to be created to change flash mode, i.e.:
Code:
try
{
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(texture);
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
if (mLightNowOn == true)
{
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
}
else
{
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequest = mPreviewRequestBuilder.build();
mCameraDevice.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, null);
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
As is mentioned in the developer docs, "Creating a session is an expensive operation and can take several hundred milliseconds, since it requires configuring the camera device's internal pipelines and allocating memory buffers for sending images to the desired targets." It definitely does, and there is a noticeable delay in my app when toggling flash mode.
I really need to be able to quickly toggle flash modes without interrupting the preview so much. Is there any way around this, or is it unavoidable due to the new API pipeline?