Zoom Camera2 Preview using TextureView

m.b. picture m.b. · Sep 22, 2015 · Viewed 17.6k times · Source

i have a Problem with my Preview Zoom for the Camera2 API. I am using a TextureView.

I want to zoom only the preview Stream that was showed in the TextureView.

I want to zoom the Area where i use the Zoom Gesture.

I use the SimpleOnScaleGestureListener!

I added following Code. The zoomingFactor and the x and y Position are right.

 private void updateTextureViewSize(float xPosi,float yPosi, float scale){
        float scaleX = 1.0f;
        float scaleY = 1.0f;




        float mVideoWidth = mCamcontrol.getmPreviewSize().getWidth();
        float mVideoHeight = mCamcontrol.getmPreviewSize().getHeight();

        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        RectF viewRect = new RectF(0, 0, 1440, 2560);
        RectF bufferRect = new RectF(0, 0, mVideoHeight, mVideoWidth);

        bufferRect.offset(xPosi - bufferRect.centerX(), yPosi -    bufferRect.centerY());

         //16:9 faktor
        scaleX = ((mScale * scale) / 9f) * 16f;
        scaleY = ((mScale * scale) / 16f) * 9f;

        Matrix matrix = new Matrix();

        matrix.setRectToRect(bufferRect, viewRect, Matrix.ScaleToFit.FILL);
        scalefactorView.setText(String.valueOf(xPosi) + "  " + String.valueOf(yPosi));

        matrix.setScale(scaleY, scaleX, xPosi, yPosi);
        matrix.postRotate(90 * (rotation - 2), xPosi, yPosi);

        mTextureView.setTransform(matrix);


}

Zooming is Right, but not the Position where i Zoom. For Example! When i zoom on the position right/middle i see only the left/top rectangle of the Stream.

I added the following pictures to unterstand the problem.

Answer

arin picture arin · Feb 9, 2016

Android Camera2 api : Pinch Zoom In/Out

Use this sample code for Camera2Basic from google developers. https://github.com/googlesamples/android-Camera2Basic

Now declare two class variables –

public float finger_spacing = 0;
public int zoom_level = 1;

and update the given onTouch() method.

public boolean onTouch(View v, MotionEvent event) {
    try {
        Activity activity = getActivity();
        CameraManager manager = (CameraManager) activity.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;
}


//Determine the space between the first two fingers
@SuppressWarnings("deprecation")
private float getFingerSpacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}