android camera2 handle zoom

匆匆过客 提交于 2019-11-30 13:20:41

问题


I'm new in Android Camera2 API. I just move my all project to the new Camera2 API. I have used the Camera2Basic example as a starting point.

I'm now trying handle zoom by adding this:

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;
}

And this:

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);
}

But after I captured, the picture result is without the zoom. How can I make it happen? Thanks all.

Update Need to add captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom); to captureStillPicture() method.


回答1:


Need to add captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom); to the captureStillPicture() method.




回答2:


You've only set the SCALER_CROP_REGION on the CaptureRequestBuilder for the recurring preview camera output. You just need to add the same crop region property to the CaptureRequestBuilder that uses the ImageSaver's JPEG Surface as the output, and you should be all set.




回答3:


Global:

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

Listener:

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
})



回答4:


Just set SCALER.CROP.REGION to the captureBuilder . You can do it in this way:

yourCapturebuilder.(CaptureRequest.SCALER_CROP_REGION, newZoom);

In other way, if you want to keep the Zoom in a preference. I suggest you do something like this: Save the Rect in a preference as a String and later on recover it to use it, or call it every time you open the camera:

Preferences.edit().putString(CameraSettings.KEY_ZOOM,newZoom.toString());

Later call this method to set the zoom dynamically:

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;

    }


来源:https://stackoverflow.com/questions/35968315/android-camera2-handle-zoom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!