第40讲 Digital Zoom缩放实战 - Android Camera2 API

本讲是Android Camera专题系列的第40讲,我们介绍Android Camera2 API专题的Digital Zoom缩放实战。

更多资源:

资源 描述
在线课程 极客笔记在线课程
知识星球 星球名称:深入浅出Android Camera
星球ID: 17296815
Wechat 极客笔记圈

判断是否支持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;

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

Android Camera2 API