在Nexus上拍摄照片时,自定义相机会显示暗图片预览

时间:2014-10-21 05:02:33

标签: java android android-camera

我已经实现了自定义相机,它在所有其他智能手机上运行良好但是当我在Nexus智能手机中拍照时,存储的图像很好但是在表面视图上向用户显示的图像的预览非常暗但不是照片存储。

我的课程在

之下

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);
}

}

2 个答案:

答案 0 :(得分:1)

我已经解决了这个问题,我使图像更亮,然后在imageview中显示它。我使用的代码如下:

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;
}

答案 1 :(得分:0)

尝试在拍摄照片

之前添加1秒的时间间隔
new Handler().postDelayed(new Runnable()
{

  @Override
  public void run(){
    camera.takePicture(mShutterCallback, null, jpegCallback);
  }

},1000);