public void autoFocus(@Nullable AutoFocusCallback cb, MotionEvent pEvent, int screenW, int screenH) { if(cb != null) { mAutoFocusCallback = cb; } if(sensorArraySize != null) { final int y = (int)pEvent.getX() / screenW * sensorArraySize.height(); final int x = (int)pEvent.getY() / screenH * sensorArraySize.width(); final int halfTouchWidth = 150; final int halfTouchHeight = 150; MeteringRectangle focusAreaTouch = new MeteringRectangle( Math.max(x-halfTouchWidth, 0), Math.max(y-halfTouchHeight, 0), halfTouchWidth*2, halfTouchHeight*2, MeteringRectangle.METERING_WEIGHT_MAX - 1); try { mCaptureSession.stopRepeating(); //Cancel any existing AF trigger (repeated touches, etc.) mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); //Now add a new AF trigger with focus region if(isMeteringAreaAFSupported) { mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusAreaTouch}); } mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); mPreviewRequestBuilder.setTag("FOCUS_TAG"); //we'll capture this later for resuming the preview! //Then we ask for a single request (not repeating!) mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); } catch(CameraAccessException ex) { Log.d("ASD", "AUTO FOCUS EXCEPTION: "+ex); } } }
public static MeteringRectangle[] regionsForNormalizedCoord(float nx, float ny, float fraction, final Rect cropRegion, int sensorOrientation) { // Compute half side length in pixels. int minCropEdge = Math.min(cropRegion.width(), cropRegion.height()); int halfSideLength = (int) (0.5f * fraction * minCropEdge); // Compute the output MeteringRectangle in sensor space. // nx, ny is normalized to the screen. // Crop region itself is specified in sensor coordinates. // Normalized coordinates, now rotated into sensor space. PointF nsc = CameraUtil.normalizedSensorCoordsForNormalizedDisplayCoords( nx, ny, sensorOrientation); int xCenterSensor = (int) (cropRegion.left + nsc.x * cropRegion.width()); int yCenterSensor = (int) (cropRegion.top + nsc.y * cropRegion.height()); Rect meteringRegion = new Rect(xCenterSensor - halfSideLength, yCenterSensor - halfSideLength, xCenterSensor + halfSideLength, yCenterSensor + halfSideLength); // Clamp meteringRegion to cropRegion. meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion.right); meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion.bottom); meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion.right); meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top, cropRegion.bottom); return new MeteringRectangle[]{new MeteringRectangle(meteringRegion, CAMERA2_REGION_WEIGHT)}; }
/** * Compute 3A regions for a sensor-referenced touch coordinate. * Returns a MeteringRectangle[] with length 1. * * @param nx x coordinate of the touch point, in normalized portrait * coordinates. * @param ny y coordinate of the touch point, in normalized portrait * coordinates. * @param fraction Fraction in [0,1]. Multiplied by min(cropRegion.width(), * cropRegion.height()) * to determine the side length of the square MeteringRectangle. * @param cropRegion Crop region of the image. * @param sensorOrientation sensor orientation as defined by * CameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION). */ private static MeteringRectangle[] regionsForNormalizedCoord( float nx, float ny, float fraction, final Rect cropRegion, int sensorOrientation) { // Compute half side length in pixels. int minCropEdge = Math.min(cropRegion.width(), cropRegion.height()); int halfSideLength = (int) (0.5f * fraction * minCropEdge); // Compute the output MeteringRectangle in sensor space. // nx, ny is normalized to the screen. // Crop region itself is specified in sensor coordinates. // Normalized coordinates, now rotated into sensor space. PointF nsc = CameraUtil.normalizedSensorCoordsForNormalizedDisplayCoords( nx, ny, sensorOrientation); int xCenterSensor = (int) (cropRegion.left + nsc.x * cropRegion.width()); int yCenterSensor = (int) (cropRegion.top + nsc.y * cropRegion.height()); Rect meteringRegion = new Rect(xCenterSensor - halfSideLength, yCenterSensor - halfSideLength, xCenterSensor + halfSideLength, yCenterSensor + halfSideLength); // Clamp meteringRegion to cropRegion. meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion.right); meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion.bottom); meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion.right); meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top, cropRegion.bottom); return new MeteringRectangle[]{new MeteringRectangle(meteringRegion, CAMERA2_REGION_WEIGHT)}; }
private CaptureRequest createCaptureRequest(@NonNull CameraDevice device) throws CameraAccessException { CaptureRequest.Builder builder = device.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); if (mMeteringRectangle != null) { builder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); builder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); } if (mCropRegion != null) { builder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion); } builder.addTarget(getPreviewSurface().getSurface()); builder.addTarget(mVideoSurface.getSurface()); return builder.build(); }
private CaptureRequest createCaptureRequest(@NonNull CameraDevice device) throws CameraAccessException { CaptureRequest.Builder builder = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); if (mMeteringRectangle != null) { builder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); builder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); } if (mCropRegion != null) { builder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion); } builder.addTarget(mPreviewSurface.getSurface()); return builder.build(); }
void takePicture(@NonNull File file, @NonNull CameraDevice device, @NonNull CameraCaptureSession session) { mPictureSurface.initializePicture(file); try { CaptureRequest.Builder builder = device.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); if (hasFlash()) { switch (getFlash()) { case AUTO: // TODO: This doesn't work :( builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); break; case ON: builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE); break; case OFF: builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); break; } } builder.addTarget(mPictureSurface.getSurface()); if (mMeteringRectangle != null) { builder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); builder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{mMeteringRectangle}); } if (mCropRegion != null) { builder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion); } session.capture(builder.build(), null /* callback */, getHandler()); } catch (CameraAccessException | IllegalStateException | IllegalArgumentException e) { // Crashes if the Camera is interacted with while still loading Log.e(TAG, "Failed to create capture request", e); onImageFailed(); } }
/** Compute 3A regions for a sensor-referenced touch coordinate. * Returns a MeteringRectangle[] with length 1. * * @param nx x coordinate of the touch point, in normalized portrait coordinates. * @param ny y coordinate of the touch point, in normalized portrait coordinates. * @param fraction Fraction in [0,1]. Multiplied by min(cropRegion.width(), cropRegion.height()) * to determine the side length of the square MeteringRectangle. * @param cropRegion Crop region of the image. * @param sensorOrientation sensor orientation as defined by * CameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION). */ private static MeteringRectangle[] regionsForNormalizedCoord(float nx, float ny, float fraction, final Rect cropRegion, int sensorOrientation) { // Compute half side length in pixels. int minCropEdge = Math.min(cropRegion.width(), cropRegion.height()); int halfSideLength = (int) (0.5f * fraction * minCropEdge); // Compute the output MeteringRectangle in sensor space. // nx, ny is normalized to the screen. // Crop region itself is specified in sensor coordinates. // Normalized coordinates, now rotated into sensor space. PointF nsc = CameraUtil.normalizedSensorCoordsForNormalizedDisplayCoords( nx, ny, sensorOrientation); int xCenterSensor = (int)(cropRegion.left + nsc.x * cropRegion.width()); int yCenterSensor = (int)(cropRegion.top + nsc.y * cropRegion.height()); Rect meteringRegion = new Rect(xCenterSensor - halfSideLength, yCenterSensor - halfSideLength, xCenterSensor + halfSideLength, yCenterSensor + halfSideLength); // Clamp meteringRegion to cropRegion. meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion.right); meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion.bottom); meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion.right); meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top, cropRegion.bottom); return new MeteringRectangle[]{new MeteringRectangle(meteringRegion, CAMERA2_REGION_WEIGHT)}; }
public static MeteringRectangle[] getZeroWeightRegion() { return ZERO_WEIGHT_3A_REGION; }
@Override public void setMeteringRectangle(@Nullable MeteringRectangle meteringRectangle) { mMeteringRectangle = meteringRectangle; }
@Nullable @Override public MeteringRectangle getMeteringRectangle() { return mMeteringRectangle; }
/** * Return AE region(s) for a sensor-referenced touch coordinate. * <p> * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AE region(s). */ public static MeteringRectangle[] aeRegionsForNormalizedCoord(float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, AE_REGION_BOX, cropRegion, sensorOrientation); }
/** * Return AF region(s) for a sensor-referenced touch coordinate. * <p> * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AF region(s). */ public static MeteringRectangle[] afRegionsForNormalizedCoord(float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, AF_REGION_BOX, cropRegion, sensorOrientation); }
/** * Return AF region(s) for a sensor-referenced touch coordinate. * <p> * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AF region(s). */ public static MeteringRectangle[] afRegionsForNormalizedCoord( float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, CameraConstants.METERING_REGION_FRACTION, cropRegion, sensorOrientation); }
/** * Return AE region(s) for a sensor-referenced touch coordinate. * <p> * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AE region(s). */ public static MeteringRectangle[] aeRegionsForNormalizedCoord( float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, CameraConstants.METERING_REGION_FRACTION, cropRegion, sensorOrientation); }
/** * Return AF region(s) for a sensor-referenced touch coordinate. * * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AF region(s). */ public static MeteringRectangle[] afRegionsForNormalizedCoord(float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, Settings3A.getAutoFocusRegionWidth(), cropRegion, sensorOrientation); }
/** * Return AE region(s) for a sensor-referenced touch coordinate. * * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AE region(s). */ public static MeteringRectangle[] aeRegionsForNormalizedCoord(float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, Settings3A.getMeteringRegionWidth(), cropRegion, sensorOrientation); }
/** * [Gcam mode only]: Return AE region(s) for a sensor-referenced touch coordinate. * * <p> * Normalized coordinates are referenced to portrait preview window with * (0, 0) top left and (1, 1) bottom right. Rotation has no effect. * </p> * * @return AE region(s). */ public static MeteringRectangle[] gcamAERegionsForNormalizedCoord(float nx, float ny, final Rect cropRegion, int sensorOrientation) { return regionsForNormalizedCoord(nx, ny, Settings3A.getGcamMeteringRegionFraction(), cropRegion, sensorOrientation); }
void setMeteringRectangle(@Nullable MeteringRectangle meteringRectangle);
@Nullable MeteringRectangle getMeteringRectangle();