本讲是Android Camera专题系列的第40讲,我们介绍Android Camera2 API专题的Digital Zoom缩放实战。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
判断是否支持Digital Zoom
float max_zoom = characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
camera_features.is_zoom_supported = max_zoom > 0.0f;
平滑的Zoom Steps计算方式
// set 20 steps per 2x factor
final int steps_per_2x_factor = 20;
//final double scale_factor = Math.pow(2.0, 1.0/(double)steps_per_2x_factor);
int n_steps =(int)( (steps_per_2x_factor * Math.log(max_zoom + 1.0e-11)) / Math.log(2.0));
final double scale_factor = Math.pow(max_zoom, 1.0/(double)n_steps);
if( MyDebug.LOG ) {
Log.i(TAG, "[Zoom] n_steps: " + n_steps);
Log.i(TAG, "[Zoom] scale_factor: " + scale_factor);
}
camera_features.zoom_ratios = new ArrayList<>();
camera_features.zoom_ratios.add(100);
double zoom = 1.0;
for(int i=0;i<n_steps-1;i++) {
zoom *= scale_factor;
camera_features.zoom_ratios.add((int)(zoom*100));
Log.i(TAG, "[Zoom] zoom:" + zoom*100);
}
camera_features.zoom_ratios.add((int)(max_zoom*100));
camera_features.max_zoom = camera_features.zoom_ratios.size()-1;
this.zoom_ratios = camera_features.zoom_ratios;
配置Zoom的SeekBar
zoomSeekBar.setOnSeekBarChangeListener(null); // clear an existing listener - don't want to call the listener when setting up the progress bar to match the existing state
zoomSeekBar.setMax(preview.getMaxZoom());
zoomSeekBar.setProgress(preview.getMaxZoom()-preview.getCameraController().getZoom());
zoomSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if( MyDebug.LOG )
Log.d(TAG, "zoom onProgressChanged: " + progress);
// note we zoom even if !fromUser, as various other UI controls (multitouch, volume key zoom, -/+ zoomcontrol)
// indirectly set zoom via this method, from setting the zoom slider
preview.zoomTo(preview.getMaxZoom() - progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
将Zoom值转换为Crop Region并设置给底层
float zoom = zoom_ratios.get(value)/100.0f;
Rect sensor_rect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
if (mPreviewBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE) != null) {
int distortionMode = mPreviewBuilder.get(CaptureRequest.DISTORTION_CORRECTION_MODE);
if (mStaticMetadata.isDistortionCorrectionSupported() &&
distortionMode == CaptureRequest.DISTORTION_CORRECTION_MODE_OFF) {
sensor_rect = characteristics.get(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
Log.i(TAG, "[Zoom] distortionMode:" + distortionMode);
}
}
int left = sensor_rect.width()/2;
int right = left;
int top = sensor_rect.height()/2;
int bottom = top;
int hwidth = (int)(sensor_rect.width() / (2.0*zoom));
int hheight = (int)(sensor_rect.height() / (2.0*zoom));
left -= hwidth;
right += hwidth;
top -= hheight;
bottom += hheight;