You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
644 lines
23 KiB
644 lines
23 KiB
package com.flurgle.camerakit;
|
|
|
|
import android.graphics.Rect;
|
|
import android.graphics.YuvImage;
|
|
import android.hardware.Camera;
|
|
import android.media.CamcorderProfile;
|
|
import android.media.MediaRecorder;
|
|
import android.os.Handler;
|
|
import android.util.Log;
|
|
import android.view.MotionEvent;
|
|
import android.view.SurfaceHolder;
|
|
import android.view.View;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.TreeSet;
|
|
|
|
import static com.flurgle.camerakit.CameraKit.Constants.FLASH_OFF;
|
|
import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS;
|
|
import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_OFF;
|
|
import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP;
|
|
import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STANDARD;
|
|
import static com.flurgle.camerakit.CameraKit.Constants.METHOD_STILL;
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public class Camera1 extends CameraImpl {
|
|
|
|
private static final String TAG = Camera1.class.getSimpleName();
|
|
|
|
private static final int FOCUS_AREA_SIZE_DEFAULT = 300;
|
|
private static final int FOCUS_METERING_AREA_WEIGHT_DEFAULT = 1000;
|
|
private static final int DELAY_MILLIS_BEFORE_RESETTING_FOCUS = 3000;
|
|
|
|
private int mCameraId;
|
|
private Camera mCamera;
|
|
private Camera.Parameters mCameraParameters;
|
|
private Camera.CameraInfo mCameraInfo;
|
|
private Size mPreviewSize;
|
|
private Size mCaptureSize;
|
|
private MediaRecorder mMediaRecorder;
|
|
private File mVideoFile;
|
|
private Camera.AutoFocusCallback mAutofocusCallback;
|
|
private boolean capturingImage = false;
|
|
|
|
private int mDisplayOrientation;
|
|
|
|
@Facing
|
|
private int mFacing;
|
|
|
|
@Flash
|
|
private int mFlash;
|
|
|
|
@Focus
|
|
private int mFocus;
|
|
|
|
@Method
|
|
private int mMethod;
|
|
|
|
@Zoom
|
|
private int mZoom;
|
|
|
|
@VideoQuality
|
|
private int mVideoQuality;
|
|
|
|
private Handler mHandler = new Handler();
|
|
|
|
Camera1(CameraListener callback, PreviewImpl preview) {
|
|
super(callback, preview);
|
|
preview.setCallback(new PreviewImpl.Callback() {
|
|
@Override
|
|
public void onSurfaceChanged() {
|
|
if (mCamera != null) {
|
|
setupPreview();
|
|
adjustCameraParameters();
|
|
}
|
|
}
|
|
});
|
|
|
|
mCameraInfo = new Camera.CameraInfo();
|
|
|
|
}
|
|
|
|
// CameraImpl:
|
|
|
|
@Override
|
|
void start() {
|
|
setFacing(mFacing);
|
|
openCamera();
|
|
if (mPreview.isReady()) setupPreview();
|
|
mCamera.startPreview();
|
|
}
|
|
|
|
@Override
|
|
void stop() {
|
|
if (mCamera != null) mCamera.stopPreview();
|
|
mHandler.removeCallbacksAndMessages(null);
|
|
releaseCamera();
|
|
}
|
|
|
|
@Override
|
|
void setDisplayOrientation(int displayOrientation) {
|
|
this.mDisplayOrientation = displayOrientation;
|
|
}
|
|
|
|
@Override
|
|
void setFacing(@Facing int facing) {
|
|
int internalFacing = new ConstantMapper.Facing(facing).map();
|
|
if (internalFacing == -1) {
|
|
return;
|
|
}
|
|
|
|
for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
|
|
Camera.getCameraInfo(i, mCameraInfo);
|
|
if (mCameraInfo.facing == internalFacing) {
|
|
mCameraId = i;
|
|
mFacing = facing;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mFacing == facing && isCameraOpened()) {
|
|
stop();
|
|
start();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void setFlash(@Flash int flash) {
|
|
if (mCameraParameters != null) {
|
|
List<String> flashes = mCameraParameters.getSupportedFlashModes();
|
|
String internalFlash = new ConstantMapper.Flash(flash).map();
|
|
if (flashes != null && flashes.contains(internalFlash)) {
|
|
mCameraParameters.setFlashMode(internalFlash);
|
|
mFlash = flash;
|
|
} else {
|
|
String currentFlash = new ConstantMapper.Flash(mFlash).map();
|
|
if (flashes == null || !flashes.contains(currentFlash)) {
|
|
mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
|
|
mFlash = FLASH_OFF;
|
|
}
|
|
}
|
|
|
|
mCamera.setParameters(mCameraParameters);
|
|
} else {
|
|
mFlash = flash;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void setFocus(@Focus int focus) {
|
|
this.mFocus = focus;
|
|
switch (focus) {
|
|
case FOCUS_CONTINUOUS:
|
|
if (mCameraParameters != null) {
|
|
detachFocusTapListener();
|
|
final List<String> modes = mCameraParameters.getSupportedFocusModes();
|
|
if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
|
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
|
} else {
|
|
setFocus(FOCUS_OFF);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FOCUS_TAP:
|
|
if (mCameraParameters != null) {
|
|
attachFocusTapListener();
|
|
final List<String> modes = mCameraParameters.getSupportedFocusModes();
|
|
if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
|
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FOCUS_OFF:
|
|
if (mCameraParameters != null) {
|
|
detachFocusTapListener();
|
|
final List<String> modes = mCameraParameters.getSupportedFocusModes();
|
|
if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
|
|
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
|
|
} else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
|
|
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
|
|
} else {
|
|
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void setMethod(@Method int method) {
|
|
this.mMethod = method;
|
|
}
|
|
|
|
@Override
|
|
void setZoom(@Zoom int zoom) {
|
|
this.mZoom = zoom;
|
|
}
|
|
|
|
@Override
|
|
void setVideoQuality(int videoQuality) {
|
|
this.mVideoQuality = videoQuality;
|
|
}
|
|
|
|
@Override
|
|
void captureImage() {
|
|
switch (mMethod) {
|
|
case METHOD_STANDARD:
|
|
|
|
// Null check required for camera here as is briefly null when View is detached
|
|
if (!capturingImage && mCamera != null) {
|
|
|
|
// Set boolean to wait for image callback
|
|
capturingImage = true;
|
|
|
|
mCamera.takePicture(null, null, null,
|
|
new Camera.PictureCallback() {
|
|
|
|
@Override
|
|
public void onPictureTaken(byte[] data, Camera camera) {
|
|
|
|
mCameraListener.onPictureTaken(data);
|
|
|
|
// Reset capturing state to allow photos to be taken
|
|
capturingImage = false;
|
|
|
|
camera.startPreview();
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
Log.w(TAG, "Unable, waiting for picture to be taken");
|
|
}
|
|
break;
|
|
|
|
case METHOD_STILL:
|
|
mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
|
|
@Override
|
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
|
new Thread(new ProcessStillTask(data, camera, calculateCaptureRotation(), new ProcessStillTask.OnStillProcessedListener() {
|
|
@Override
|
|
public void onStillProcessed(final YuvImage yuv) {
|
|
mCameraListener.onPictureTaken(yuv);
|
|
}
|
|
})).start();
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
void startVideo() {
|
|
initMediaRecorder();
|
|
prepareMediaRecorder();
|
|
mMediaRecorder.start();
|
|
}
|
|
|
|
@Override
|
|
void endVideo() {
|
|
mMediaRecorder.stop();
|
|
mMediaRecorder.release();
|
|
mMediaRecorder = null;
|
|
mCameraListener.onVideoTaken(mVideoFile);
|
|
}
|
|
|
|
@Override
|
|
Size getCaptureResolution() {
|
|
if (mCaptureSize == null && mCameraParameters != null) {
|
|
TreeSet<Size> sizes = new TreeSet<>();
|
|
for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
|
|
sizes.add(new Size(size.width, size.height));
|
|
}
|
|
|
|
TreeSet<AspectRatio> aspectRatios = findCommonAspectRatios(
|
|
mCameraParameters.getSupportedPreviewSizes(),
|
|
mCameraParameters.getSupportedPictureSizes()
|
|
);
|
|
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
|
|
|
|
Iterator<Size> descendingSizes = sizes.descendingIterator();
|
|
Size size;
|
|
while (descendingSizes.hasNext() && mCaptureSize == null) {
|
|
size = descendingSizes.next();
|
|
if (targetRatio == null || targetRatio.matches(size)) {
|
|
mCaptureSize = size;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return mCaptureSize;
|
|
}
|
|
|
|
@Override
|
|
Size getPreviewResolution() {
|
|
if (mPreviewSize == null && mCameraParameters != null) {
|
|
TreeSet<Size> sizes = new TreeSet<>();
|
|
for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
|
|
sizes.add(new Size(size.width, size.height));
|
|
}
|
|
|
|
TreeSet<AspectRatio> aspectRatios = findCommonAspectRatios(
|
|
mCameraParameters.getSupportedPreviewSizes(),
|
|
mCameraParameters.getSupportedPictureSizes()
|
|
);
|
|
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
|
|
|
|
Iterator<Size> descendingSizes = sizes.descendingIterator();
|
|
Size size;
|
|
while (descendingSizes.hasNext() && mPreviewSize == null) {
|
|
size = descendingSizes.next();
|
|
if (targetRatio == null || targetRatio.matches(size)) {
|
|
mPreviewSize = size;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return mPreviewSize;
|
|
}
|
|
|
|
@Override
|
|
boolean isCameraOpened() {
|
|
return mCamera != null;
|
|
}
|
|
|
|
// Internal:
|
|
|
|
private void openCamera() {
|
|
if (mCamera != null) {
|
|
releaseCamera();
|
|
}
|
|
|
|
mCamera = Camera.open(mCameraId);
|
|
mCameraParameters = mCamera.getParameters();
|
|
|
|
adjustCameraParameters();
|
|
mCamera.setDisplayOrientation(calculatePreviewRotation());
|
|
|
|
mCameraListener.onCameraOpened();
|
|
}
|
|
|
|
private void setupPreview() {
|
|
try {
|
|
if (mPreview.getOutputClass() == SurfaceHolder.class) {
|
|
mCamera.setPreviewDisplay(mPreview.getSurfaceHolder());
|
|
} else {
|
|
mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
|
|
}
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
private void releaseCamera() {
|
|
if (mCamera != null) {
|
|
mCamera.release();
|
|
mCamera = null;
|
|
mCameraParameters = null;
|
|
mPreviewSize = null;
|
|
mCaptureSize = null;
|
|
mCameraListener.onCameraClosed();
|
|
}
|
|
}
|
|
|
|
private int calculatePreviewRotation() {
|
|
if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
|
return ((mCameraInfo.orientation - mDisplayOrientation) + 360 + 180) % 360;
|
|
} else {
|
|
return (mCameraInfo.orientation - mDisplayOrientation + 360) % 360;
|
|
}
|
|
}
|
|
|
|
private int calculateCaptureRotation() {
|
|
int previewRotation = calculatePreviewRotation();
|
|
if (mCameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
|
//Front is flipped
|
|
return (previewRotation + 180 + 2*mDisplayOrientation + 720) %360;
|
|
} else {
|
|
return previewRotation;
|
|
}
|
|
}
|
|
|
|
private void adjustCameraParameters() {
|
|
boolean invertPreviewSizes = mDisplayOrientation%180 != 0;
|
|
mPreview.setTruePreviewSize(
|
|
invertPreviewSizes? getPreviewResolution().getHeight() : getPreviewResolution().getWidth(),
|
|
invertPreviewSizes? getPreviewResolution().getWidth() : getPreviewResolution().getHeight()
|
|
);
|
|
|
|
mCameraParameters.setPreviewSize(
|
|
getPreviewResolution().getWidth(),
|
|
getPreviewResolution().getHeight()
|
|
);
|
|
|
|
mCameraParameters.setPictureSize(
|
|
getCaptureResolution().getWidth(),
|
|
getCaptureResolution().getHeight()
|
|
);
|
|
int rotation = calculateCaptureRotation();
|
|
mCameraParameters.setRotation(rotation);
|
|
|
|
setFocus(mFocus);
|
|
setFlash(mFlash);
|
|
|
|
mCamera.setParameters(mCameraParameters);
|
|
}
|
|
|
|
private TreeSet<AspectRatio> findCommonAspectRatios(List<Camera.Size> previewSizes, List<Camera.Size> captureSizes) {
|
|
Set<AspectRatio> previewAspectRatios = new HashSet<>();
|
|
for (Camera.Size size : previewSizes) {
|
|
if (size.width >= CameraKit.Internal.screenHeight && size.height >= CameraKit.Internal.screenWidth) {
|
|
previewAspectRatios.add(AspectRatio.of(size.width, size.height));
|
|
}
|
|
}
|
|
|
|
Set<AspectRatio> captureAspectRatios = new HashSet<>();
|
|
for (Camera.Size size : captureSizes) {
|
|
captureAspectRatios.add(AspectRatio.of(size.width, size.height));
|
|
}
|
|
|
|
TreeSet<AspectRatio> output = new TreeSet<>();
|
|
for (AspectRatio aspectRatio : previewAspectRatios) {
|
|
if (captureAspectRatios.contains(aspectRatio)) {
|
|
output.add(aspectRatio);
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
private void initMediaRecorder() {
|
|
mMediaRecorder = new MediaRecorder();
|
|
mCamera.unlock();
|
|
|
|
mMediaRecorder.setCamera(mCamera);
|
|
|
|
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
|
|
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
|
|
|
|
mMediaRecorder.setProfile(getCamcorderProfile(mVideoQuality));
|
|
|
|
mVideoFile = new File(mPreview.getView().getContext().getExternalFilesDir(null), "video.mp4");
|
|
mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath());
|
|
mMediaRecorder.setOrientationHint(mCameraInfo.orientation);
|
|
}
|
|
|
|
private void prepareMediaRecorder() {
|
|
try {
|
|
mMediaRecorder.prepare();
|
|
} catch (IllegalStateException e) {
|
|
e.printStackTrace();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private CamcorderProfile getCamcorderProfile(@VideoQuality int videoQuality) {
|
|
CamcorderProfile camcorderProfile = null;
|
|
switch (videoQuality) {
|
|
case CameraKit.Constants.VIDEO_QUALITY_480P:
|
|
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_480P)) {
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_480P);
|
|
} else {
|
|
return getCamcorderProfile(CameraKit.Constants.VIDEO_QUALITY_LOWEST);
|
|
}
|
|
break;
|
|
|
|
case CameraKit.Constants.VIDEO_QUALITY_720P:
|
|
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_720P)) {
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_720P);
|
|
} else {
|
|
return getCamcorderProfile(CameraKit.Constants.VIDEO_QUALITY_480P);
|
|
}
|
|
break;
|
|
|
|
case CameraKit.Constants.VIDEO_QUALITY_1080P:
|
|
if (CamcorderProfile.hasProfile(mCameraId, CamcorderProfile.QUALITY_1080P)) {
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_1080P);
|
|
} else {
|
|
return getCamcorderProfile(CameraKit.Constants.VIDEO_QUALITY_720P);
|
|
}
|
|
break;
|
|
|
|
case CameraKit.Constants.VIDEO_QUALITY_2160P:
|
|
try {
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_2160P);
|
|
} catch (Exception e) {
|
|
return getCamcorderProfile(CameraKit.Constants.VIDEO_QUALITY_HIGHEST);
|
|
}
|
|
break;
|
|
|
|
case CameraKit.Constants.VIDEO_QUALITY_HIGHEST:
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_HIGH);
|
|
break;
|
|
|
|
case CameraKit.Constants.VIDEO_QUALITY_LOWEST:
|
|
camcorderProfile = CamcorderProfile.get(mCameraId, CamcorderProfile.QUALITY_LOW);
|
|
break;
|
|
}
|
|
|
|
return camcorderProfile;
|
|
}
|
|
|
|
void setTapToAutofocusListener(Camera.AutoFocusCallback callback) {
|
|
if (this.mFocus != FOCUS_TAP) {
|
|
throw new IllegalArgumentException("Please set the camera to FOCUS_TAP.");
|
|
}
|
|
|
|
this.mAutofocusCallback = callback;
|
|
}
|
|
|
|
private int getFocusAreaSize() {
|
|
return FOCUS_AREA_SIZE_DEFAULT;
|
|
}
|
|
|
|
private int getFocusMeteringAreaWeight() {
|
|
return FOCUS_METERING_AREA_WEIGHT_DEFAULT;
|
|
}
|
|
|
|
private void detachFocusTapListener() {
|
|
mPreview.getView().setOnTouchListener(null);
|
|
}
|
|
|
|
private void attachFocusTapListener() {
|
|
mPreview.getView().setOnTouchListener(new View.OnTouchListener() {
|
|
@Override
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
if (event.getAction() == MotionEvent.ACTION_UP) {
|
|
if (mCamera != null) {
|
|
Camera.Parameters parameters = mCamera.getParameters();
|
|
String focusMode = parameters.getFocusMode();
|
|
Rect rect = calculateFocusArea(event.getX(), event.getY());
|
|
List<Camera.Area> meteringAreas = new ArrayList<>();
|
|
meteringAreas.add(new Camera.Area(rect, getFocusMeteringAreaWeight()));
|
|
if (parameters.getMaxNumFocusAreas() != 0 && focusMode != null &&
|
|
(focusMode.equals(Camera.Parameters.FOCUS_MODE_AUTO) ||
|
|
focusMode.equals(Camera.Parameters.FOCUS_MODE_MACRO) ||
|
|
focusMode.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) ||
|
|
focusMode.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
|
|
) {
|
|
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
|
parameters.setFocusAreas(meteringAreas);
|
|
if (parameters.getMaxNumMeteringAreas() > 0) {
|
|
parameters.setMeteringAreas(meteringAreas);
|
|
}
|
|
if(!parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
|
|
return false; //cannot autoFocus
|
|
}
|
|
mCamera.setParameters(parameters);
|
|
mCamera.autoFocus(new Camera.AutoFocusCallback() {
|
|
@Override
|
|
public void onAutoFocus(boolean success, Camera camera) {
|
|
resetFocus(success, camera);
|
|
}
|
|
});
|
|
} else if (parameters.getMaxNumMeteringAreas() > 0) {
|
|
if(!parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
|
|
return false; //cannot autoFocus
|
|
}
|
|
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
|
parameters.setFocusAreas(meteringAreas);
|
|
parameters.setMeteringAreas(meteringAreas);
|
|
|
|
mCamera.setParameters(parameters);
|
|
mCamera.autoFocus(new Camera.AutoFocusCallback() {
|
|
@Override
|
|
public void onAutoFocus(boolean success, Camera camera) {
|
|
resetFocus(success, camera);
|
|
}
|
|
});
|
|
} else {
|
|
mCamera.autoFocus(new Camera.AutoFocusCallback() {
|
|
@Override
|
|
public void onAutoFocus(boolean success, Camera camera) {
|
|
if (mAutofocusCallback != null) {
|
|
mAutofocusCallback.onAutoFocus(success, camera);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
private void resetFocus(final boolean success, final Camera camera) {
|
|
mHandler.removeCallbacksAndMessages(null);
|
|
mHandler.postDelayed(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (camera != null) {
|
|
camera.cancelAutoFocus();
|
|
Camera.Parameters params = camera.getParameters();
|
|
if (params.getFocusMode() != Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
|
|
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
|
params.setFocusAreas(null);
|
|
params.setMeteringAreas(null);
|
|
camera.setParameters(params);
|
|
}
|
|
|
|
if (mAutofocusCallback != null) {
|
|
mAutofocusCallback.onAutoFocus(success, camera);
|
|
}
|
|
}
|
|
}
|
|
}, DELAY_MILLIS_BEFORE_RESETTING_FOCUS);
|
|
}
|
|
|
|
private Rect calculateFocusArea(float x, float y) {
|
|
int centerX = clamp(Float.valueOf((x / mPreview.getView().getWidth()) * 2000 - 1000).intValue(), getFocusAreaSize());
|
|
int centerY = clamp(Float.valueOf((y / mPreview.getView().getHeight()) * 2000 - 1000).intValue(), getFocusAreaSize());
|
|
return new Rect(
|
|
centerX - getFocusAreaSize() / 2,
|
|
centerY - getFocusAreaSize() / 2,
|
|
centerX + getFocusAreaSize() / 2,
|
|
centerY + getFocusAreaSize() / 2
|
|
);
|
|
}
|
|
|
|
private int clamp(int touchCoordinateInCameraReper, int focusAreaSize) {
|
|
int result;
|
|
if (Math.abs(touchCoordinateInCameraReper) + focusAreaSize / 2 > 1000) {
|
|
if (touchCoordinateInCameraReper > 0) {
|
|
result = 1000 - focusAreaSize / 2;
|
|
} else {
|
|
result = -1000 + focusAreaSize / 2;
|
|
}
|
|
} else {
|
|
result = touchCoordinateInCameraReper - focusAreaSize / 2;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|