Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zoom photo preview #30

Closed
freakdragon opened this issue Aug 8, 2017 · 3 comments
Closed

Zoom photo preview #30

freakdragon opened this issue Aug 8, 2017 · 3 comments

Comments

@freakdragon
Copy link

freakdragon commented Aug 8, 2017

Trying to add slider zoomer to Camera for photos.
Added to CameraController:

float getCurrentZoom();
void setCurrentZoom(float zoom);
float getMaxZoom();

Added to Camera1Controller

@Override
    public float getCurrentZoom() {
        return cameraManager.getCurrentZoom();
    }
    @Override
    public float getMaxZoom() {
        return cameraManager.getMaxZoom();
    }
    @Override
    public void setCurrentZoom(float zoom) {
        cameraManager.setCurrentZoom(zoom);
    }

Added to Camera2Controller

      @Override
    public float getCurrentZoom() {
        return camera2Manager.getCurrentZoom();
    }
    @Override
    public float getMaxZoom() {
        return camera2Manager.getMaxZoom();
    }
    @Override
    public void setCurrentZoom(float zoom) {
        camera2Manager.setCurrentZoom(zoom);
    }

Added to CameraManager

    float getCurrentZoom();
    void setCurrentZoom(float zoom);
    float getMaxZoom();

Added to AnncaCameraActivity

protected float getCurrentZoom() {
        return getCameraController().getCurrentZoom();
    }
    protected float getMaxZoom() {
        return getCameraController().getMaxZoom();
    }
    protected void setCurrentZoom(float zoom) {
        getCameraController().setCurrentZoom(zoom);
    }

I'm getting value of it by max zoom of camera1

Camera.Parameters parameter = camera.getParameters();
        if(parameter.isZoomSupported()) {
            return parameter.getMaxZoom();
        }

and camera2

(manager.getCameraCharacteristics(this.currentCameraId).get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10

SeekBar impementation:

minZoom = getMinZoom();
        maxZoom = getMaxZoom() - 1;
        final int step = 1;
        seekBarBottom.setMax(Math.round(maxZoom - minZoom));
        seekBarBottom.setOnSeekBarChangeListener(
                new SeekBar.OnSeekBarChangeListener()
                {
                    @Override
                    public void onStopTrackingTouch(SeekBar seekBar) {}
                    @Override
                    public void onStartTrackingTouch(SeekBar seekBar) {}
                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                        
                        setCurrentZoom(Math.round(minZoom + (progress * step)));
                    }
                }
        );

I've added to Camera1Manager

public void setCurrentZoom(float zoom) {
        Camera.Parameters parameter = camera.getParameters();
        if(getCurrentZoom() < getMaxZoom()) {
            parameter.setZoom(Math.round(zoom));
            camera.setParameters(parameter);
        }
    }

Works fine.

I've added to Camera2Manager

protected int zoomLevel = 1;
public void setCurrentZoom(float zoomLevel) {
        try {
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(this.currentCameraId);
            float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM))*10;
            Rect m = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
            if((zoomLevel <= maxZoom) && (zoomLevel > 1)) {
                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) zoomLevel;
                int cropH = difH / 100 * (int) zoomLevel;
                cropW -= cropW & 3;
                cropH -= cropH & 3;
                Rect zoom = new Rect(cropW, cropH, m.width() - cropW, m.height() - cropH);
                try {
                    previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoom);
                    captureSession.capture(previewRequestBuilder.build(), captureCallback, backgroundHandler);
                } catch (Exception e) {
                    Log.e(TAG, "Error updating preview: ", e);
                }
                this.zoomLevel = (int) zoomLevel;
            }
        } catch (Exception e) {
            Log.e(TAG, "Error during camera init");
        }
    }

It zooms but immediately returns to normal state. Is there some listener that changes its state back?

@freakdragon freakdragon changed the title Zoom photo Zoom photo preview Aug 8, 2017
@freakdragon
Copy link
Author

changed
captureSession.capture(previewRequestBuilder.build(), captureCallback, backgroundHandler);
to
captureSession.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, backgroundHandler);
and it worked.
Now I'm fighting with zoom. It doesn't crop zoomed image. I'll write again, if I'll gain a victory

@memfis19
Copy link
Owner

memfis19 commented Aug 8, 2017

Hi, I'll take a look, thank you for reporting.

@freakdragon
Copy link
Author

freakdragon commented Aug 9, 2017

changed function in Camera2Manager to

@Override
    public void setCurrentZoom(float zoomLevel) {
        Rect zoomRect = getZoomRect(zoomLevel);
        if(zoomRect != null) {
            try {
                previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
                captureSession.setRepeatingRequest(previewRequestBuilder.build(), captureCallback, backgroundHandler);
            } catch (Exception e) {
                Log.e(TAG, "Error updating preview: ", e);
            }
            this.zoomLevel = (int) zoomLevel;
        }
    }

    private Rect getZoomRect(float zoomLevel) {
        try {
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(this.currentCameraId);
            float maxZoom = (characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)) * 10;
            Rect activeRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
            if((zoomLevel <= maxZoom) && (zoomLevel > 1)) {
                int minW = (int) (activeRect.width() / maxZoom);
                int minH = (int) (activeRect.height() / maxZoom);
                int difW = activeRect.width() - minW;
                int difH = activeRect.height() - minH;
                int cropW = difW / 100 * (int) zoomLevel;
                int cropH = difH / 100 * (int) zoomLevel;
                cropW -= cropW & 3;
                cropH -= cropH & 3;
                return new Rect(cropW, cropH, activeRect.width() - cropW, activeRect.height() - cropH);
            } else if(zoomLevel == 0){
                return new Rect(0, 0, activeRect.width(), activeRect.height());
            }
            return null;
        } catch (Exception e) {
            Log.e(TAG, "Error during camera init");
            return null;
        }
    }

and added cropping to CaptureStillPicture() function in Camera2Manager

private void captureStillPicture() {
        try {
            if (null == cameraDevice) {
                return;
            }
            final CaptureRequest.Builder captureBuilder =
                    cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(imageReader.getSurface());

            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getPhotoOrientation(configurationProvider.getSensorPosition()));

            Rect zoomRect = getZoomRect(zoomLevel);
            if(zoomRect == null) {
                zoomRect = getZoomRect(0);
            }
            captureBuilder.set(CaptureRequest.SCALER_CROP_REGION, zoomRect);
            
            CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    Log.d(TAG, "onCaptureCompleted: ");
                }
            };

            captureSession.stopRepeating();
            captureSession.capture(captureBuilder.build(), CaptureCallback, null);
            setCurrentZoom(0);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Error during capturing picture");
        }
    }

Works fine with photos (didn't try with video). Check it. And add zooming to this library if you want.
P.S. I'm setting zoom to 0, because zoom resets after taking photo. And that's why after take photo I'm setting my zoom seekbar's progress to 0 too. Don't know why it's so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants