package com.yydcdut.note.model.camera.impl2;
import android.annotation.TargetApi;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.util.Range;
import com.yydcdut.note.model.camera.ICameraSettingModel;
import com.yydcdut.note.utils.camera.param.Size;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yuyidong on 16/2/10.
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2SettingModel implements ICameraSettingModel {
private int mCameraNumber;
private CameraCharacteristics mCameraCharacteristics;
private CaptureRequest.Builder mBuilder;
public Camera2SettingModel(CameraCharacteristics cameraCharacteristics, int cameraNumber) {
mCameraCharacteristics = cameraCharacteristics;
mCameraNumber = cameraNumber;
}
public void setCaptureRequestBuilder(CaptureRequest.Builder builder) {
mBuilder = builder;
}
@Override
public int getNumberOfCameras() {
return mCameraNumber;
}
@Override
public boolean isFlashSupported() {
return mCameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
}
@Override
public List<Size> getSupportPreviewSizes() {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
return null;
}
android.util.Size[] supports = map.getOutputSizes(SurfaceTexture.class);
List<Size> sizeList = new ArrayList<>(supports.length);
for (android.util.Size size : supports) {
sizeList.add(Size.translate(size.getWidth(), size.getHeight()));
}
return sizeList;
}
@Override
public List<Size> getSupportPictureSizes() {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
return null;
}
android.util.Size[] supports = map.getOutputSizes(ImageFormat.JPEG);
List<Size> sizeList = new ArrayList<>(supports.length);
for (android.util.Size size : supports) {
sizeList.add(Size.translate(size.getWidth(), size.getHeight()));
}
return sizeList;
}
@Override
public boolean isZoomSupported() {
return mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM) >= 1;
}
@Override
public boolean isFocusSupported() {
return mCameraCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) > 0;
}
@Override
public int getMaxZoom() {
return (int) (mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM) * 100);
}
@Override
public int getMaxExposureCompensation() {
Range<Integer> range = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
return range.getUpper();
}
@Override
public int getMinExposureCompensation() {
Range<Integer> range = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
return range.getLower();
}
public List<Size> getSupportYUV420888Sizes() {
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
return null;
}
android.util.Size[] supports = map.getOutputSizes(ImageFormat.YUV_420_888);
List<Size> sizeList = new ArrayList<>(supports.length);
for (android.util.Size size : supports) {
sizeList.add(Size.translate(size.getWidth(), size.getHeight()));
}
return sizeList;
}
@Override
public void setDisplayOrientation(int degree) {
}
@Override
public void setFlash(int flashState) {
switch (flashState) {
case FLASH_OFF:
mBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
break;
case FLASH_AUTO:
mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
break;
case FLASH_ON:
mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
break;
default:
break;
}
doChange();
}
@Override
public int getFlash() {
switch (mBuilder.get(CaptureRequest.CONTROL_AE_MODE)) {
case CaptureRequest.CONTROL_AE_MODE_OFF:
return FLASH_OFF;
case CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH:
return FLASH_AUTO;
case CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH:
return FLASH_ON;
}
return FLASH_OFF;
}
@Override
public void setZoom(int value) {
//value ---> 0 ~ max*100
float zoom = ((float) value / 100);
Rect rect = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
float max = mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
float scale = 1 - ((max - zoom) / max);//scale是从 0 ~ 1,当为0的时候没有变化,当为1的时候最大放大
float change = max * scale + 1.0f * (1 - scale);//change是从 1.0 ~ max,当为1.0的时候没有变化,当为max的时候最大放大
if (change > max) {
return;
}
int centerX = rect.centerX();
int centerY = rect.centerY();
int width = rect.width();
int height = rect.height();
float newWidth = width / change;
float newHeight = height / change;
float left = centerX - newWidth / 2;
float top = centerY - newHeight / 2;
float right = newWidth / 2 + centerX;
float bottom = newHeight / 2 + centerY;
Rect newRect = new Rect((int) left, (int) top, (int) right, (int) bottom);
mBuilder.set(CaptureRequest.SCALER_CROP_REGION, newRect);
doChange();
}
@Override
public int getZoom() {
float max = mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
Rect currentRect = mBuilder.get(CaptureRequest.SCALER_CROP_REGION);
Rect totalRect = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (currentRect == null) {
currentRect = totalRect;
}
float scaleX = ((float) totalRect.width()) / currentRect.width();
float scaleY = ((float) totalRect.height()) / currentRect.height();
float change = scaleX > scaleY ? scaleY : scaleX;//change是从 1.0 ~ max,当为1.0的时候没有变化,当为max的时候最大放大
float scale = (change - 1.0f) / (max - 1.0f);//scale是从 0 ~ 1,当为0的时候没有变化,当为1的时候最大放大
return (int) (scale * max * 100);
}
@Override
public void setExposureCompensation(int value) {
mBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, value);
doChange();
}
@Override
public int calculateZoom(int firstZoomValue, float firstCurrentSpan, float currectCurrentSpan) {
if (!isZoomSupported()) {
return -1;
}
int value = (int) (((currectCurrentSpan / firstCurrentSpan - 1) * getMaxZoom()) + firstZoomValue);
if (value > getMaxZoom()) {
return getMaxZoom();
} else if (value < 0) {
return 0;
} else {
return value;
}
}
public Rect getActiveArraySize() {
return mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
}
private OnParameterChangedListener mOnParameterChangedListener;
public void setOnParameterChangedListener(OnParameterChangedListener onParameterChangedListener) {
mOnParameterChangedListener = onParameterChangedListener;
}
public interface OnParameterChangedListener {
void onChanged(CaptureRequest.Builder builder);
}
private void doChange() {
if (mOnParameterChangedListener != null) {
mOnParameterChangedListener.onChanged(mBuilder);
}
}
}