android camera2手柄变焦
android camera2 handle zoom
我是 Android Camera2 API 的新手。
我只是将所有项目移至新的 Camera2 API。我使用 Camera2Basic example 作为起点。
我现在正在尝试通过添加以下内容来处理缩放:
public boolean onTouchEvent(MotionEvent event) {
try {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId);
float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10;
Rect m = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
int action = event.getAction();
float current_finger_spacing;
if (event.getPointerCount() > 1) {
// Multi touch logic
current_finger_spacing = getFingerSpacing(event);
if(finger_spacing != 0){
if(current_finger_spacing > finger_spacing && maxZoom > zoom_level){
zoom_level++;
}
else if (current_finger_spacing < finger_spacing && zoom_level > 1){
zoom_level--;
}
int minW = (int) (m.width() / maxZoom);
int minH = (int) (m.height() / maxZoom);
int difW = m.width() - minW;
int difH = m.height() - minH;
int cropW = difW /100 *(int)zoom_level;
int cropH = difH /100 *(int)zoom_level;
cropW -= cropW & 3;
cropH -= cropH & 3;
Rect zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
mPreviewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
}
finger_spacing = current_finger_spacing;
}
else{
if (action == MotionEvent.ACTION_UP) {
//single touch logic
}
}
try {
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
null);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
catch (NullPointerException ex)
{
ex.printStackTrace();
}
}
catch (CameraAccessException e)
{
throw new RuntimeException("can not access camera.", e);
}
return true;
}
还有这个:
private float getFingerSpacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
但是我拍出来的结果是没有放大的。
我怎样才能让它发生?
谢谢大家
更新
需要将 captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
添加到 captureStillPicture()
方法。
您只在 CaptureRequestBuilder
上设置了 SCALER_CROP_REGION
用于循环预览相机输出。您只需要将相同的裁剪区域 属性 添加到使用 ImageSaver
的 JPEG Surface
作为输出的 CaptureRequestBuilder
,您应该已经准备就绪。
需要添加captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
captureStillPicture()
方法。
只需将 SCALER.CROP.REGION
设置为 captureBuilder
。你可以这样做:
yourCapturebuilder.(CaptureRequest.SCALER_CROP_REGION, newZoom);
换句话说,如果你想在首选项中保留缩放。我建议你做这样的事情:将 Rect 保存为 String 的首选项,然后恢复它以使用它,或者每次打开相机时调用它:
Preferences.edit().putString(CameraSettings.KEY_ZOOM,newZoom.toString());
稍后调用此方法动态设置缩放:
public boolean setZoomValue(CaptureRequest.Builder builder) {
Log.i(TAG,"zoom preference value " + mPreferences.getString(CameraSettings.KEY_ZOOM,null));
String rawZoomValue = mPreferences.getString(CameraSettings.KEY_ZOOM, null);
if (rawZoomValue == null)
return false;
rawZoomValue = rawZoomValue.replaceAll("[Rect() ]", "");
String[] rectZoomList = rawZoomValue.split(",|\-|\)|\(");
Rect zoomValue = new Rect( Integer.parseInt(rectZoomList[0]), Integer.parseInt(rectZoomList[1]), Integer.parseInt(rectZoomList[2]),Integer.parseInt(rectZoomList[3]));
builder.set(CaptureRequest.SCALER_CROP_REGION, zoomValue);
Log.i(TAG, "Zoom applied: " + zoomValue);
return true;
}
全球:
companion object {
private const val ZOOM_GESTURE_SENSITIVITY = .0005f
private const val MAX_ZOOM_FACTOR = 3f
}
private var fingerDistance: Float? = null
private var zoom = 1f
听众:
textureView.setOnTouchListener({ _, event ->
if (event.action != MotionEvent.ACTION_MOVE || event.pointerCount <= 1) {
fingerDistance = null
return@setOnTouchListener true
}
val newFingerDistance = with(event) {
val x = getX(0) - getX(1)
val y = getY(0) - getY(1)
sqrt(x * x + y * y) * resources.displayMetrics.density
}
if (fingerDistance != null) {
val manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val characteristics = manager.getCameraCharacteristics(cameraId)
val maxZoom = min(MAX_ZOOM_FACTOR, characteristics.get(
CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))
val zoomChange = (newFingerDistance - fingerDistance!!) * ZOOM_GESTURE_SENSITIVITY
zoom = min(maxZoom, max(1f, zoom + zoomChange))
val sensorSize = characteristics.get(
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
val cropW = (sensorSize.width() * (1 - 1 / zoom) / 2).toInt()
val cropH = (sensorSize.width() * (1 - 1 / zoom) / 2).toInt()
val zoomRect = Rect(cropW, cropH,
sensorSize.width() - cropW,
sensorSize.height() - cropH)
previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect)
}
fingerDistance = newFingerDistance
try {
captureSession
?.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, null)
} catch (e: Exception) {
e.printStackTrace()
}
true
})
我是 Android Camera2 API 的新手。 我只是将所有项目移至新的 Camera2 API。我使用 Camera2Basic example 作为起点。
我现在正在尝试通过添加以下内容来处理缩放:
public boolean onTouchEvent(MotionEvent event) {
try {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId);
float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10;
Rect m = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
int action = event.getAction();
float current_finger_spacing;
if (event.getPointerCount() > 1) {
// Multi touch logic
current_finger_spacing = getFingerSpacing(event);
if(finger_spacing != 0){
if(current_finger_spacing > finger_spacing && maxZoom > zoom_level){
zoom_level++;
}
else if (current_finger_spacing < finger_spacing && zoom_level > 1){
zoom_level--;
}
int minW = (int) (m.width() / maxZoom);
int minH = (int) (m.height() / maxZoom);
int difW = m.width() - minW;
int difH = m.height() - minH;
int cropW = difW /100 *(int)zoom_level;
int cropH = difH /100 *(int)zoom_level;
cropW -= cropW & 3;
cropH -= cropH & 3;
Rect zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
mPreviewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
}
finger_spacing = current_finger_spacing;
}
else{
if (action == MotionEvent.ACTION_UP) {
//single touch logic
}
}
try {
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
null);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
catch (NullPointerException ex)
{
ex.printStackTrace();
}
}
catch (CameraAccessException e)
{
throw new RuntimeException("can not access camera.", e);
}
return true;
}
还有这个:
private float getFingerSpacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
但是我拍出来的结果是没有放大的。 我怎样才能让它发生? 谢谢大家
更新
需要将 captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
添加到 captureStillPicture()
方法。
您只在 CaptureRequestBuilder
上设置了 SCALER_CROP_REGION
用于循环预览相机输出。您只需要将相同的裁剪区域 属性 添加到使用 ImageSaver
的 JPEG Surface
作为输出的 CaptureRequestBuilder
,您应该已经准备就绪。
需要添加captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
captureStillPicture()
方法。
只需将 SCALER.CROP.REGION
设置为 captureBuilder
。你可以这样做:
yourCapturebuilder.(CaptureRequest.SCALER_CROP_REGION, newZoom);
换句话说,如果你想在首选项中保留缩放。我建议你做这样的事情:将 Rect 保存为 String 的首选项,然后恢复它以使用它,或者每次打开相机时调用它:
Preferences.edit().putString(CameraSettings.KEY_ZOOM,newZoom.toString());
稍后调用此方法动态设置缩放:
public boolean setZoomValue(CaptureRequest.Builder builder) {
Log.i(TAG,"zoom preference value " + mPreferences.getString(CameraSettings.KEY_ZOOM,null));
String rawZoomValue = mPreferences.getString(CameraSettings.KEY_ZOOM, null);
if (rawZoomValue == null)
return false;
rawZoomValue = rawZoomValue.replaceAll("[Rect() ]", "");
String[] rectZoomList = rawZoomValue.split(",|\-|\)|\(");
Rect zoomValue = new Rect( Integer.parseInt(rectZoomList[0]), Integer.parseInt(rectZoomList[1]), Integer.parseInt(rectZoomList[2]),Integer.parseInt(rectZoomList[3]));
builder.set(CaptureRequest.SCALER_CROP_REGION, zoomValue);
Log.i(TAG, "Zoom applied: " + zoomValue);
return true;
}
全球:
companion object {
private const val ZOOM_GESTURE_SENSITIVITY = .0005f
private const val MAX_ZOOM_FACTOR = 3f
}
private var fingerDistance: Float? = null
private var zoom = 1f
听众:
textureView.setOnTouchListener({ _, event ->
if (event.action != MotionEvent.ACTION_MOVE || event.pointerCount <= 1) {
fingerDistance = null
return@setOnTouchListener true
}
val newFingerDistance = with(event) {
val x = getX(0) - getX(1)
val y = getY(0) - getY(1)
sqrt(x * x + y * y) * resources.displayMetrics.density
}
if (fingerDistance != null) {
val manager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val characteristics = manager.getCameraCharacteristics(cameraId)
val maxZoom = min(MAX_ZOOM_FACTOR, characteristics.get(
CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))
val zoomChange = (newFingerDistance - fingerDistance!!) * ZOOM_GESTURE_SENSITIVITY
zoom = min(maxZoom, max(1f, zoom + zoomChange))
val sensorSize = characteristics.get(
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
val cropW = (sensorSize.width() * (1 - 1 / zoom) / 2).toInt()
val cropH = (sensorSize.width() * (1 - 1 / zoom) / 2).toInt()
val zoomRect = Rect(cropW, cropH,
sensorSize.width() - cropW,
sensorSize.height() - cropH)
previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect)
}
fingerDistance = newFingerDistance
try {
captureSession
?.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, null)
} catch (e: Exception) {
e.printStackTrace()
}
true
})