如何在拍摄照片时通过Java获取Android手机摄像头的曝光补偿等级?

Bri*_*ian 11 java android opencv javacameraview autoexposurecompensation

如何在拍摄照片时从Android手机获取AutoExposureCompensation等级(亮度)?

我可以拍张照.我可以访问摄像机的参数,包括曝光补偿(当我检查时总是为零),但我需要在拍摄照片时获得AE补偿等级,而不是之前和之后.

背景:我希望在特定时间拍摄的所有照片都使用相同的AE补偿等级拍摄照片.我不希望Android相机通常会对曝光级别或白平衡进行数百次调整.我想获得一次,并为所有后续照片设置相同的设置.

我已经尝试过使用"意图"来拍照,OpenCV,碎片等.我似乎无法使用其中任何一种获得AE补偿设置.这是我尝试过的最新代码,从JavaCameraView的扩展版本开始:

import org.opencv.android.JavaCameraView;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
@SuppressWarnings("deprecation")
public class NewJavaCameraView extends JavaCameraView implements PictureCallback {

public int getExposureCompensation(){
    return mCamera.getParameters().getExposureCompensation();
}
 @SuppressWarnings("deprecation")
 public void takePicture(final String fileName) {
    Log.i(TAG, "Taking picture");
    this.mPictureFileName = fileName;

    Camera.Parameters params = mCamera.getParameters();
    int exposureComp = params.getExposureCompensation();
    mCamera.setPreviewCallback(null);

    // PictureCallback is implemented by the current class
    int otherexposureComp =this.getExposureCompensation();
    mCamera.takePicture(null, null, this);
}

 @SuppressWarnings("deprecation")
 @Override
 public void onPictureTaken(byte[] data, Camera camera) {

    Camera.Parameters params = mCamera.getParameters();
    int exposureComp = params.getExposureCompensation();
    int otherexposureComp =this.getExposureCompensation();
    mCamera.startPreview();
    mCamera.setPreviewCallback(this);

    // Write the image in a file (in jpeg format)
    try {
        FileOutputStream fos = new FileOutputStream(mPictureFileName);

        fos.write(data);
        fos.close();

    } catch (java.io.IOException e) {
        Log.e("Picture", "photoCallback", e);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是Android View中使用上述类的一些代码:

public class DiscPhoto extends Activity implements CvCameraViewListener2, OnTouchListener {
 private static final String TAG = "OCVSample::Activity";
 private NewJavaCameraView mOpenCvCameraView;
 private List<Size> mResolutionList;

 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                mOpenCvCameraView.setOnTouchListener(DiscPhoto.this);
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

public DiscPhoto() {
    Log.i(TAG, "Instantiated new " + this.getClass());
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    Log.i(TAG, "called onCreate");
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    setContentView(R.layout.activity_disc_photo);

    mOpenCvCameraView = (NewJavaCameraView) findViewById(R.id.discPhotoPage);
    mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
    mOpenCvCameraView.setCvCameraViewListener(this);
}

@SuppressLint("SimpleDateFormat")
@Override
public boolean onTouch(View v, MotionEvent event) {
    Log.i(TAG,"onTouch event");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
    String currentDateandTime = sdf.format(new Date());
    String fileName = Environment.getExternalStorageDirectory().getPath() +
            "/sample_picture_" + currentDateandTime + ".jpg";
    mOpenCvCameraView.takePicture(fileName);
    Toast.makeText(this, fileName + " saved", Toast.LENGTH_SHORT).show();
    return false;
}
Run Code Online (Sandbox Code Playgroud)

man*_*shg 4

我认为camera2 API(https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html)足以满足您的需求。

来源:https ://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#CONTROL_AE_LOCK

由于相机设备具有正在进行的请求管道,因此被锁定的设置不一定对应于从相机设备接收到的最新捕捉结果中存在的设置,因为甚至之前可能已经发生了额外的捕捉和 AE 更新结果发出去了。如果应用程序在自动和手动控制之间切换并希望消除切换期间的任何闪烁,建议执行以下步骤:

  1. 以自动 AE 模式启动:
  2. 锁定自动曝光
  3. 等待第一个已锁定 AE 的结果输出
  4. 将曝光设置从该结果复制到请求中,将请求设置为手动 AE
  5. 提交捕获请求,继续根据需要运行手动 AE。

也根据AE模式的描述(相同来源)

当设置为任何 ON 模式时,相机设备自动曝光例程为给定捕获的覆盖字段选择的值将在其 CaptureResult 中可用。

因此,一旦发出第一个 CaptureRequest,您就可以使用TotalCaptureResult以下回调:

void onCaptureCompleted (CameraCaptureSession session, 
                CaptureRequest request, 
                TotalCaptureResult result)
{
       int aecompensationlevel = result.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION)
}
Run Code Online (Sandbox Code Playgroud)