Android如何实现双指缩放?
How to implement pinch zooming in Android?
经过对SO的一些研究,我找不到使用android.hardware.camera实现缩放的方法。我正在使用 SeekBar 但这不是我需要的。有谁知道我在哪里可以找到适用于 Android SKD >= 15 的示例?
在我的 cameraFragment 中,我正在使用 OnSeekBarChangeListener
在 onProgressChanged 方法中,我设置了相机的缩放。
seekbar.setOnSeekBarChangeListener(this);
.....
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
try {
Camera.Parameters params = camera.getParameters();
params.setZoom(progress);
currentZoomLevel = progress;
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
//set zoom level value
try {
float ratio = ((float) params.getZoomRatios().get(progress)) / 100;
tvZoomLevel.setText(String.format("%.1fX", ratio));
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
1.Override onTouchEvent(MotionEvent event)
2.Get相机的最大缩放级别param
3.Adjust 捏合放大相机 param
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get the pointer ID
Camera.Parameters params = mCamera.getParameters();
int action = event.getAction();
if (event.getPointerCount() > 1) {
// handle multi-touch events
if (action == MotionEvent.ACTION_POINTER_DOWN) {
mDist = getFingerSpacing(event);
} else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
mCamera.cancelAutoFocus();
handleZoom(event, params);
}
} else {
// handle single touch events
if (action == MotionEvent.ACTION_UP) {
handleFocus(event, params);
}
}
return true;
}
private void handleZoom(MotionEvent event, Camera.Parameters params) {
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
float newDist = getFingerSpacing(event);
if (newDist > mDist) {
//zoom in
if (zoom < maxZoom)
zoom++;
} else if (newDist < mDist) {
//zoom out
if (zoom > 0)
zoom--;
}
mDist = newDist;
params.setZoom(zoom);
mCamera.setParameters(params);
}
public void handleFocus(MotionEvent event, Camera.Parameters params) {
int pointerId = event.getPointerId(0);
int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
List<String> supportedFocusModes = params.getSupportedFocusModes();
if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean b, Camera camera) {
// currently set to auto-focus on single touch
}
});
}
}
/** Determine the space between the first two fingers */
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);
}
This certain step help you a basic implemention of your requirement.
经过对SO的一些研究,我找不到使用android.hardware.camera实现缩放的方法。我正在使用 SeekBar 但这不是我需要的。有谁知道我在哪里可以找到适用于 Android SKD >= 15 的示例?
在我的 cameraFragment 中,我正在使用 OnSeekBarChangeListener 在 onProgressChanged 方法中,我设置了相机的缩放。
seekbar.setOnSeekBarChangeListener(this);
.....
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
try {
Camera.Parameters params = camera.getParameters();
params.setZoom(progress);
currentZoomLevel = progress;
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
//set zoom level value
try {
float ratio = ((float) params.getZoomRatios().get(progress)) / 100;
tvZoomLevel.setText(String.format("%.1fX", ratio));
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
1.Override onTouchEvent(MotionEvent event)
2.Get相机的最大缩放级别param
3.Adjust 捏合放大相机 param
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get the pointer ID
Camera.Parameters params = mCamera.getParameters();
int action = event.getAction();
if (event.getPointerCount() > 1) {
// handle multi-touch events
if (action == MotionEvent.ACTION_POINTER_DOWN) {
mDist = getFingerSpacing(event);
} else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
mCamera.cancelAutoFocus();
handleZoom(event, params);
}
} else {
// handle single touch events
if (action == MotionEvent.ACTION_UP) {
handleFocus(event, params);
}
}
return true;
}
private void handleZoom(MotionEvent event, Camera.Parameters params) {
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
float newDist = getFingerSpacing(event);
if (newDist > mDist) {
//zoom in
if (zoom < maxZoom)
zoom++;
} else if (newDist < mDist) {
//zoom out
if (zoom > 0)
zoom--;
}
mDist = newDist;
params.setZoom(zoom);
mCamera.setParameters(params);
}
public void handleFocus(MotionEvent event, Camera.Parameters params) {
int pointerId = event.getPointerId(0);
int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
List<String> supportedFocusModes = params.getSupportedFocusModes();
if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean b, Camera camera) {
// currently set to auto-focus on single touch
}
});
}
}
/** Determine the space between the first two fingers */
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);
}
This certain step help you a basic implemention of your requirement.