Created
October 29, 2015 13:18
-
-
Save FisherKK/ca209e4cb740b65b4ee6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Preview extends ViewGroup implements SurfaceHolder.Callback { | |
private final String TAG = "Preview"; | |
SurfaceView mSurfaceView; | |
Camera.Size mPreviewSize; | |
List<Camera.Size> mSupportedPreviewSizes; | |
Camera mCamera; | |
Preview(Context context) { | |
super(context); | |
mSurfaceView = new SurfaceView(context); | |
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().getSupportedPreviewSizes(); | |
mCamera.setDisplayOrientation(90); | |
requestLayout(); | |
} | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); | |
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); | |
viewHeight = AppTools.getScreenHeight(CameraActivity.this); | |
viewWidth = width; | |
setMeasuredDimension(width, height); | |
if (mSupportedPreviewSizes != null) { | |
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); | |
} | |
} | |
@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.height; | |
previewHeight=mPreviewSize.width; | |
} | |
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(SurfaceHolder holder) { | |
try { | |
if (mCamera != null) { | |
mCamera.setPreviewDisplay(holder); | |
} | |
} catch (IOException exception) { | |
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); | |
} | |
} | |
public void surfaceDestroyed(SurfaceHolder holder) { | |
if (mCamera != null) { | |
mCamera.stopPreview(); | |
} | |
} | |
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { | |
final double ASPECT_TOLERANCE = 0.1; | |
double targetRatio=(double)h / w; | |
if (sizes == null) return null; | |
Camera.Size optimalSize = null; | |
double minDiff = Double.MAX_VALUE; | |
int targetHeight = h; | |
for (Camera.Size size : sizes) { | |
double ratio = (double) size.width / size.height; | |
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; | |
if (Math.abs(size.height - targetHeight) < minDiff) { | |
optimalSize = size; | |
minDiff = Math.abs(size.height - targetHeight); | |
} | |
} | |
if (optimalSize == null) { | |
minDiff = Double.MAX_VALUE; | |
for (Camera.Size size : sizes) { | |
if (Math.abs(size.height - targetHeight) < minDiff) { | |
optimalSize = size; | |
minDiff = Math.abs(size.height - targetHeight); | |
} | |
} | |
} | |
return optimalSize; | |
} | |
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { | |
if (mCamera != null) { | |
Camera.Parameters parameters = mCamera.getParameters(); | |
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); | |
if (parameters.getSupportedPictureSizes() != null) { | |
parameters = initialCameraPictureSize(parameters, mPreviewSize.width, mPreviewSize.height); | |
} | |
parameters = adjustFocusToDevice(parameters); | |
makeCameraViewSquare(); | |
requestLayout(); | |
mCamera.setParameters(parameters); | |
mCamera.startPreview(); | |
} | |
} | |
public Camera.Parameters initialCameraPictureSize(Camera.Parameters parameters, int w, int h) { | |
List<Camera.Size> sizes = parameters.getSupportedPictureSizes(); | |
final double ASPECT_TOLERANCE = 0.1; | |
double targetRatio= AppTools.getScreenRatio(CameraActivity.this); | |
if (sizes == null) return null; | |
Camera.Size optimalSize = null; | |
double minDiff = Double.MAX_VALUE; | |
int targetHeight = h; | |
for (Camera.Size size : sizes) { | |
double ratio = (double) size.width / size.height; | |
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; | |
if (Math.abs(size.height - targetHeight) < minDiff) { | |
optimalSize = size; | |
if (optimalSize.height > 1600 || optimalSize.width > 1600) continue; | |
minDiff = Math.abs(size.height - targetHeight); | |
} | |
} | |
if (optimalSize == null) { | |
minDiff = Double.MAX_VALUE; | |
for (Camera.Size size : sizes) { | |
if (Math.abs(size.height - targetHeight) < minDiff) { | |
optimalSize = size; | |
minDiff = Math.abs(size.height - targetHeight); | |
} | |
} | |
} | |
parameters.setPictureSize(optimalSize.width,optimalSize.height); | |
return parameters; | |
} | |
private void makeCameraViewSquare() { | |
topView.setLayoutParams(new RelativeLayout.LayoutParams( | |
viewWidth, | |
(viewHeight - viewWidth)/2 | |
)); | |
RelativeLayout.LayoutParams bottomViewParams = new RelativeLayout.LayoutParams( | |
viewWidth, | |
(viewHeight - viewWidth)/2 | |
); | |
bottomViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); | |
bottomView.setLayoutParams(bottomViewParams); | |
llCameraButtonbar.setLayoutParams(bottomViewParams); | |
} | |
} | |
private Camera.Parameters adjustFocusToDevice(Camera.Parameters parameters) { | |
List<String> focusModesList = parameters.getSupportedFocusModes(); | |
for (int i=0; i<=focusModesList.size()-1; i++) { | |
if (currentCamera != FRONT_CAMERA) { | |
if (focusModesList.get(i).contains("continuous-picture")) { | |
currentFocusMode = CONTINUOUS_PICTURE_MODE; | |
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); | |
} else if (focusModesList.get(i).contains("auto")) { | |
currentFocusMode = AUTO_FOCUS_MODE; | |
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); | |
} | |
} | |
} | |
return parameters; | |
} | |
public boolean onTouchEvent(MotionEvent event) { | |
int eventaction = event.getAction(); | |
switch (eventaction) { | |
case MotionEvent.ACTION_DOWN: | |
if (currentCamera == FRONT_CAMERA) { | |
return true; | |
} | |
if (currentFocusMode != null && currentFocusMode == AUTO_FOCUS_MODE && !isTakePictureClicked) { | |
mCamera.autoFocus(new Camera.AutoFocusCallback() { | |
@Override | |
public void onAutoFocus(boolean success, Camera camera) { | |
} | |
}); | |
} | |
break; | |
case MotionEvent.ACTION_MOVE: | |
break; | |
case MotionEvent.ACTION_UP: | |
break; | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment