下面列出了怎么用android.hardware.camera2.CameraMetadata的API类实例代码及写法,或者点击链接到github查看源代码。
private static boolean isMonochrome(@NonNull String deviceName, @NonNull CameraManager cameraManager) {
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(deviceName);
int[] capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
if (capabilities != null) {
for (int capability : capabilities) {
if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
return true;
}
}
}
} catch (CameraAccessException e) {
return false;
}
return false;
}
private void setDefaultCaptureRequest(final CaptureRequest.Builder request,
final boolean trigger) {
if (hasAutoFocus()) {
request.set(CaptureRequest.CONTROL_AF_MODE, mAutoFocusMode);
if (trigger) {
request.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
}
}
if (hasAutoExposure()) {
request.set(CaptureRequest.CONTROL_AE_MODE, mAutoExposureMode);
}
setWhiteBalance(request);
// Light が ON の場合は、CONTROL_AE_MODE を CONTROL_AE_MODE_ON にする。
if (mIsTouchOn) {
mUseTouch = true;
request.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
request.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
}
}
@RequiresApi(21)
public static int getLowestSupportedHardwareLevel(@NonNull Context context) {
@SuppressLint("RestrictedApi") CameraManager cameraManager = CameraManagerCompat.from(context).unwrap();
try {
int supported = maxHardwareLevel();
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer hwLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (hwLevel == null || hwLevel == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}
supported = smallerHardwareLevel(supported, hwLevel);
}
return supported;
} catch (CameraAccessException e) {
Log.w(TAG, "Failed to enumerate cameras", e);
return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}
}
private void start() {
checkIsOnCameraThread();
Logging.d(TAG, "start");
try {
cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
} catch (final CameraAccessException e) {
reportError("getCameraCharacteristics(): " + e.getMessage());
return;
}
cameraOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
isCameraFrontFacing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING)
== CameraMetadata.LENS_FACING_FRONT;
findCaptureFormat();
openCamera();
}
/**
* Lock the focus as the first step for a still image capture.
*/
private void lockFocus() {
Log.d(TAG, "lockFocus: ");
try {
// This is how to tell the camera to lock focus.
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_START);
// Tell #mCaptureCallback to wait for the lock.
mState = STATE_WAITING_LOCK;
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
Log.e(TAG, "CameraAccessException: " + e);
e.printStackTrace();
}
}
/************************************************************************************************
* Unlock the focus. This method should be called when still image capture sequence is finished.
************************************************************************************************/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void unlockFocus() {
try {
// Reset the autofucos trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Generate a human-readable string of the given capture request and write
* it to the given file.
*/
public static void toFile(String title, CameraMetadata<?> metadata, File file)
{
try
{
// Will append if the file already exists.
FileWriter writer = new FileWriter(file, true);
if (metadata instanceof CaptureRequest)
{
dumpMetadata(title, (CaptureRequest) metadata, writer);
} else if (metadata instanceof CaptureResult)
{
dumpMetadata(title, (CaptureResult) metadata, writer);
} else
{
writer.close();
throw new IllegalArgumentException("Cannot generate debug data from type "
+ metadata.getClass().getName());
}
writer.close();
} catch (IOException ex)
{
Log.e(TAG, "Could not write capture data to file.", ex);
}
}
@Override
public List<FaceDetectMode> getSupportedFaceDetectModes()
{
int[] modes = mCameraCharacteristics.get(
CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
List<FaceDetectMode> oneModes = new ArrayList<>(modes.length);
for (int i = 0; i < modes.length; i++)
{
if (modes[i] == CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL)
{
oneModes.add(FaceDetectMode.FULL);
}
if (modes[i] == CameraMetadata.STATISTICS_FACE_DETECT_MODE_SIMPLE)
{
oneModes.add(FaceDetectMode.SIMPLE);
}
if (modes[i] == CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF)
{
oneModes.add(FaceDetectMode.NONE);
}
}
return oneModes;
}
/**
* Request preview capture stream with AF_MODE_CONTINUOUS_PICTURE.
*
* @param tag
* @return true if request was build and sent successfully.
*/
private boolean repeatingPreview(Object tag)
{
try
{
CaptureRequest.Builder builder = mDevice.
createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(mPreviewSurface);
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
addBaselineCaptureKeysToRequest(builder);
mCaptureSession.setRepeatingRequest(builder.build(), mCaptureCallback, mCameraHandler);
Log.v(TAG, String.format("Sent repeating Preview request, zoom = %.2f", mZoomValue));
return true;
} catch (CameraAccessException ex)
{
Log.e(TAG, "Could not access camera setting up preview.", ex);
return false;
}
}
/**
* Request preview capture stream with auto focus trigger cycle.
*/
private void sendAutoFocusTriggerCaptureRequest(Object tag)
{
try
{
// Step 1: Request single frame CONTROL_AF_TRIGGER_START.
CaptureRequest.Builder builder;
builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(mPreviewSurface);
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
mControlAFMode = CameraMetadata.CONTROL_AF_MODE_AUTO;
addBaselineCaptureKeysToRequest(builder);
builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
builder.setTag(tag);
mCaptureSession.capture(builder.build(), mCaptureCallback, mCameraHandler);
// Step 2: Call repeatingPreview to update mControlAFMode.
repeatingPreview(tag);
resumeContinuousAFAfterDelay(FOCUS_HOLD_MILLIS);
} catch (CameraAccessException ex)
{
Log.e(TAG, "Could not execute preview request.", ex);
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
Log.d("WOW", "update preview....");
if (null == mCameraDevice) {
return;
}
try {
if (isAutoFocusSupported()) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE/*CONTROL_AF_MODE_AUTO*/);
Log.d("WOW", "support autofocus");
} else {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
Log.d("WOW", "not support autofocus");
}
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE,
CameraMetadata.CONTROL_MODE_AUTO);
// HandlerThread thread = new HandlerThread("CameraPreview");
// thread.start();
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
// setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is finished.
*/
private void unlockFocus() {
Log.d(TAG, "unlockFocus: ");
try {
if (mEnabledAutoFocus) {
// Reset the autofucos trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
}
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void process(CaptureResult result) {
Integer state = result.get(CaptureResult.CONTROL_AF_STATE);
if (null == state) {
return;
}
Log.d(TAG, "process: CONTROL_AF_STATE: " + state);
if (state == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED || state == CaptureResult
.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
Log.d(TAG, "process: start normal preview");
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest
.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.FLASH_MODE_OFF);
startPreview();
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
if(mFlashSupported) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mFlashMode);
}
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void switchHdrMode() {
switch (mHdrMode) {
case 0:
mHdrMode = 1;
mIvHdr.setImageResource(R.mipmap.hdr_on);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_HDR);
break;
case 1:
mHdrMode = 0;
mIvHdr.setImageResource(R.mipmap.hdr_off);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_DISABLED);
break;
}
try {
mCaptureSession.setRepeatingRequest(
mPreviewRequestBuilder.build(),
mPreCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
return;
}
}
/**
* @required: <uses-permission android:name="android.permission.FLASHLIGHT"/>
*/
public void disableLantern() {
CameraCharacteristics characteristics = getCameraCharacteristics();
if (characteristics == null) return;
if (characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
if (builderInputSurface != null) {
try {
builderInputSurface.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
cameraCaptureSession.setRepeatingRequest(builderInputSurface.build(),
faceDetectionEnabled ? cb : null, null);
lanternEnable = false;
} catch (Exception e) {
Log.e(TAG, "Error", e);
}
}
}
}
/**
* Reconfigure the camera with new flash and focus settings.
*/
private void reconfigureCamera() {
if (mCameraDevice != null && mCaptureSession != null) {
try {
mCaptureSession.stopRepeating();
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
doPreviewConfiguration();
}
catch (CameraAccessException | IllegalStateException e) {
mCameraCallback.onCameraError("Failed to reconfigure the camera", "rec1", e);
}
}
}
private void doPreviewConfiguration() {
if (mCamera == null) {
return;
}
try {
// mPreviewBuilder = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// mPreviewBuilder.addTarget(surfaceView.getHolder().getSurface());
// mPreviewBuilder.addTarget(mImageReader.getSurface());
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
// mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
// mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mFps[mFps.length -1 ]);
mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), mPreCaptureCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void unlockFocus() {
try {
// AFのロックを解除する(トリガーをキャンセルする)
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// AFトリガーのキャンセルを実行する
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mInterface.getBackgroundHandler());
// プレビューを継続するためsetRepeatingRequestメソッドを実行する
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mInterface.getBackgroundHandler());
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* Unlock the focus. This method should be called when still image capture sequence is
* finished.
*/
private void unlockFocus() {
try {
// Reset the auto-focus trigger
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
setAutoFlash(mPreviewRequestBuilder);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private static Integer choiceAutoFocusMode(final Context context,
final CameraManager cameraManager,
final String cameraId) throws CameraAccessException {
PackageManager pkgMgr = context.getPackageManager();
if (!pkgMgr.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS)) {
return null;
}
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
int[] afModes = characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
if (afModes == null) {
return null;
}
for (int i = 0; i < afModes.length; i++) {
if (afModes[i] == CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE) {
return afModes[i];
}
}
return null;
}
@RequiresApi(21)
private static int smallerHardwareLevel(int levelA, int levelB) {
int[] hardwareInfoOrdering = getHardwareInfoOrdering();
for (int hwInfo : hardwareInfoOrdering) {
if (levelA == hwInfo || levelB == hwInfo) return hwInfo;
}
return CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}
@Override
public boolean isFrontFacing(String deviceName) {
CameraCharacteristics characteristics = getCameraCharacteristics(deviceName);
return characteristics != null
&& characteristics.get(CameraCharacteristics.LENS_FACING)
== CameraMetadata.LENS_FACING_FRONT;
}
@Override
public boolean isBackFacing(String deviceName) {
CameraCharacteristics characteristics = getCameraCharacteristics(deviceName);
return characteristics != null
&& characteristics.get(CameraCharacteristics.LENS_FACING)
== CameraMetadata.LENS_FACING_BACK;
}
public void updateCaptureResultPanel(
final Float fl,
final Long exposureTimeNs, final Integer afMode) {
final String sfl = String.format(Locale.getDefault(), "%.3f", fl);
final String sexpotime =
exposureTimeNs == null ?
"null ms" :
String.format(Locale.getDefault(), "%.2f ms",
exposureTimeNs / 1000000.0);
String safMode;
switch (afMode) {
case CameraMetadata.CONTROL_AF_MODE_OFF:
safMode = "AF locked";
break;
default:
safMode = "AF unlocked";
break;
}
final String saf = safMode;
runOnUiThread(new Runnable() {
@Override
public void run() {
mCaptureResultText.setText(sfl + " " + sexpotime + " " + saf);
}
});
}
private void setExposureAndIso() {
Long exposureNanos = CameraCaptureActivity.mDesiredExposureTime;
Long desiredIsoL = 30L * 30000000L / exposureNanos;
Integer desiredIso = desiredIsoL.intValue();
if (!expoStats.isEmpty()) {
int index = expoStats.size() / 2;
Long actualExpo = expoStats.get(index).mExposureNanos;
Integer actualIso = expoStats.get(index).mIso;
if (actualExpo <= exposureNanos) {
exposureNanos = actualExpo;
desiredIso = actualIso;
} else {
desiredIsoL = actualIso * actualExpo / exposureNanos;
desiredIso = desiredIsoL.intValue();
}
}
// fix exposure
mPreviewRequestBuilder.set(
CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF);
Range<Long> exposureTimeRange = mCameraCharacteristics.get(
CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
if (exposureTimeRange != null) {
Log.d(TAG, "exposure time range " + exposureTimeRange.toString());
}
mPreviewRequestBuilder.set(
CaptureRequest.SENSOR_EXPOSURE_TIME, exposureNanos);
Log.d(TAG, "Exposure time set to " + exposureNanos);
// fix ISO
Range<Integer> isoRange = mCameraCharacteristics.get(
CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
if (isoRange != null) {
Log.d(TAG, "ISO range " + isoRange.toString());
}
mPreviewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, desiredIso);
Log.d(TAG, "ISO set to " + desiredIso);
}