Syed Wajahat Ali Syed Wajahat Ali - 3 months ago 26
Java Question

Custom camera shows dark picture preview when photo taken on Nexus

I have implemented a custom camera and it works well on all other smartphones but when i take photo in Nexus smartphones the image stored is good but the preview of the image shown to user on surface view is very dark but not the photo that is stored.

My classes are below

Preview.java

package com.custom.customcamera;


import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";

SurfaceView mSurfaceView;
SurfaceHolder mHolder;
int heightmax ;
int widthmax ;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;

@SuppressWarnings("deprecation")
Preview(Context context, SurfaceView sv) {
super(context);

mSurfaceView = sv;
// addView(mSurfaceView);

mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPictureSizes();
requestLayout();

// get Camera parameters
Camera.Parameters params = mCamera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
mCamera.setParameters(params);
}

params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
params.setSceneMode(Parameters.SCENE_MODE_AUTO);
//params.setPreviewFormat(256);
int index = params.getExposureCompensation ();
params.setExposureCompensation(index);
mCamera.setParameters(params);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);

if (mSupportedPreviewSizes != null) {

mPreviewSize=maxSize();

}
}

public Size maxSize(){

// heightmax =0;
// widthmax =0;
Size sizeMax=mSupportedPreviewSizes.get(0);
//long totalsize = heightmax*widthmax;
//long maxsize=mSupportedPreviewSizes.get(0).height*mSupportedPreviewSizes.get(0).width;

for(Size size:mSupportedPreviewSizes){
if(size.height*size.width>sizeMax.width*sizeMax.height){
sizeMax = size;

}
}

return sizeMax;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);

final int width = r - l;
final int height = b - t;

int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}

// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}

public void surfaceCreated(final SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (Exception exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}

public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.release();
//mCamera.stopPreview();
mCamera = null;
}
}

Camera.AutoFocusCallback mnAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
}
};

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if(mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();

mCamera.setParameters(parameters);
mCamera.startPreview();

}
}

}


CameraActivity.java

package com.custom.customcamera;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import android.util.Base64;
import com.kut.kutcamera.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.media.ExifInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class CameraActivity extends Activity {
Activity context;
Preview preview;
Camera camera;
ImageView fotoButton;
//ImageView foto;
ImageView CancelButton;
ImageView ConfirmButton;
//SurfaceView surfaceView;
String path = "";
static CameraListener listener;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);

context=this;

Intent intent = getIntent();
String tempPath = intent.getStringExtra("Path");

this.path = tempPath;

fotoButton = (ImageView) findViewById(R.id.imageView_foto);
ConfirmButton = (ImageView) findViewById(R.id.imageView_confirm);
CancelButton = (ImageView) findViewById(R.id.imageView_cancel);
//foto = (ImageView) findViewById(R.id.imageView_photoTaken);

//surfaceView=(SurfaceView)findViewById(R.id.CustomCameraFragment);
ConfirmButton.setVisibility(View.INVISIBLE);
CancelButton.setVisibility(View.INVISIBLE);
//foto.setVisibility(View.INVISIBLE);

preview = new Preview(this,
(SurfaceView) findViewById(R.id.CustomCameraFragment));
FrameLayout frame = (FrameLayout) findViewById(R.id.preview);
frame.addView(preview);
preview.setKeepScreenOn(true);
fotoButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
fotoButton.setImageResource(R.drawable.camera_focused);
takeFocusedPicture();
} catch (Exception e) {
}
fotoButton.setClickable(false);
}
});
}

public void initializeListener(CameraListener listener)
{
this.listener = listener;
}

private int cameraId = 0;

@Override
protected void onResume() {
super.onResume();
// TODO Auto-generated method stub
try
{
if(camera==null){
cameraId = findFrontFacingCamera();
camera = Camera.open(cameraId);

Camera.Parameters params = camera.getParameters();
params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
params.setSceneMode(Parameters.SCENE_MODE_AUTO);
//params.setPreviewFormat(256);
int index = params.getExposureCompensation ();
params.setExposureCompensation(index);
camera.setParameters(params);
camera.startPreview();
camera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera mcamera) {
camera.release();
camera = Camera.open();
Log.d("Camera died", "error camera");
}
});
}

if (camera != null) {
if (Build.VERSION.SDK_INT >= 14)
setCameraDisplayOrientation(context, CameraInfo.CAMERA_FACING_FRONT, camera);
preview.setCamera(camera);
}
}

catch(Exception ex)
{
String s = ex.toString();
}
}

private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
break;
}
}
return cameraId;
}

private void setCameraDisplayOrientation(Activity activity, int cameraId,
android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}

int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}

Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, final Camera camera) {

try{
Camera.Parameters params = camera.getParameters();
//params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
//params.setSceneMode(Parameters.SCENE_MODE_AUTO);
//params.setPreviewFormat(256);
//int index = params.getExposureCompensation ();
//params.setExposureCompensation(index);
//camera.setParameters(params);
//camera.autoFocus(null);
camera.takePicture(mShutterCallback, null, jpegCallback);

}catch(Exception e){
String err = e.getMessage();
}

}
};

Camera.ShutterCallback mShutterCallback = new ShutterCallback() {

@Override
public void onShutter() {
// TODO Auto-generated method stub

}
};
public void takeFocusedPicture() {
camera.autoFocus(mAutoFocusCallback);
}

PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
}
};

String ImagePath = "";

PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(final byte[] data, final Camera cameraSec) {
camera.stopPreview();
//Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
fotoButton.setVisibility(View.INVISIBLE);

ConfirmButton.setVisibility(View.VISIBLE);
CancelButton.setVisibility(View.VISIBLE);
//surfaceView.setVisibility(SurfaceView.GONE);
//foto.setVisibility(View.VISIBLE);
//foto.setVisibility(ImageView.VISIBLE);
//foto.setImageBitmap(image);
ConfirmButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
try
{
ConfirmButton.setImageResource(R.drawable.confirmfocused);

FileOutputStream outStream = null;
Calendar c = Calendar.getInstance();
File videoDirectory = new File(path);

if (!videoDirectory.exists()) {
videoDirectory.mkdirs();
}

ImagePath = path + "/" + UUID.randomUUID().toString() + "_" +new Date().getTime() + ".jpg";
outStream = new FileOutputStream(ImagePath);
outStream.write(data);
outStream.close();

Bitmap realImage;
ExifInterface exif = new ExifInterface(ImagePath);

int rotation = (int)exifOrientationToDegrees(
exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL));

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;

realImage = BitmapFactory.decodeFile(ImagePath, options);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
realImage.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] byteArrayImage = baos.toByteArray();

String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
if(listener != null)
listener.PictureTaken(encodedImage,ImagePath,ImagePath.substring(ImagePath.lastIndexOf("/")+1));

Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
LaunchIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(LaunchIntent);

finish();
}
catch(Exception ex){}
return false;
}
});

CancelButton.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {

//surfaceView.setVisibility(SurfaceView.VISIBLE);
CancelButton.setImageResource(R.drawable.cancelfocused);

ConfirmButton.setVisibility(View.INVISIBLE);
CancelButton.setVisibility(View.INVISIBLE);
//foto.setVisibility(View.INVISIBLE);

CancelButton.setImageResource(R.drawable.cancel);
ConfirmButton.setImageResource(R.drawable.confirm);

fotoButton.setVisibility(View.VISIBLE);

fotoButton.setClickable(true);
fotoButton.setImageResource(R.drawable.camera);
cameraSec.startPreview();

return false;
}
});
}
};

private float exifOrientationToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}

public static Bitmap rotate(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}

}

Answer

I have got a work around for this issue i made the image brighter and then shown it in an imageview. The code i used is given below:

foto.setColorFilter(brightIt(100));//foto is my ImageView
//and below is the brightIt func
public static ColorMatrixColorFilter brightIt(int fb) {
    ColorMatrix cmB = new ColorMatrix();
    cmB.set(new float[] { 
        1, 0, 0, 0, fb,
        0, 1, 0, 0, fb,
        0, 0, 1, 0, fb,
        0, 0, 0, 1, 0   });

    ColorMatrix colorMatrix = new ColorMatrix();
    colorMatrix.set(cmB);
    //Canvas c = new Canvas(b2);
    //Paint paint = new Paint();
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(colorMatrix);
    //paint.setColorFilter(f);   
   return f;
}
Comments