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

feat: Android Camera v2 API #339

Open
wants to merge 38 commits into
base: master
Choose a base branch
from

Conversation

dpa99c
Copy link

@dpa99c dpa99c commented Jun 22, 2024

This PR contains a rewrite of the Android implementation to use the Camera v2 API instead of the deprecated Camera API.

The main reason for this change is to fix issues I was encountering with the existing implementation where the camera preview/captured image from this plugin did not correspond the camera preview/captured image from the default Camera app. i.e. this fixes #275

It also opens the way to fetch the device's camera details and select a specific camera/lens based on these [see #256].
While the fetch side is implemented by this PR (getCameraCharacteristics()), the selection of a specific camera/lens is not (as I didn't need it for my use case).

I also implements getZoom(), setZoom() and getMaxZoom() on both Android & iOS, reworking my previous PR #326 on Android to work with Camera v2 API.

@forgr-owner
Copy link

Hey @dpa99c feel free to propose your PR here: Cap-go/camera-preview#61
There is bounty of $100

@varshith257
Copy link

varshith257 commented Jul 7, 2024

@dpa99c Is this changes works? Maybe a demo video demonstrating this changes could be good to add in PR description.

It could get easy for @pbowyer or @arielhernandezmusa to get quick reviewed. Hope this get merged soon. I am waiting for the Camera2 API to be integrated in the capacitor soon :)

@eggbeard
Copy link

This is a huge step in the right direction and deserves some attention to get it merged.
I am struggling to get the preview to display with the correct aspect ratio, with this PR

# Conflicts:
#	android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
…s to ensure all forms of exception are caught

# Conflicts:
#	android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java
#	android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
Send error and log messages as plugin events back to JS layer
…and do not attempt to restore previous orientation

# Conflicts:
#	android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
@dpa99c dpa99c mentioned this pull request Nov 12, 2024
@dpa99c
Copy link
Author

dpa99c commented Nov 12, 2024

I am using this test project to validate the plugin functionality:
https://github.com/dpa99c/capacitor-camera-preview-test

@eggbeard
Copy link

eggbeard commented Nov 13, 2024

@dpa99c Thanks for the test project. I believe that using a square preview in the test project is camouflaging a bug in computing the transformation matrix for the preview, since width and height are often the same and many aspect ratios collapse out to 1.

If you make the width, twice the height, then it becomes apparent that, in landscape mode the preview looks stretched vertically, while in portrait the opposite happens (the preview is squashed in Y)

I took a look through configureTransform, but to be honest did not understand it very well. It seems likely that scaleY is calculated wrongly, but trying to work out what it should be hurts my brain.

I have only tested on Android. I don't have access to an apple device

return mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
}

private void configureTransform(int viewWidth, int viewHeight) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still haven't pinned this one down, but something like:

private void configureTransform(int viewWidth, int viewHeight) {
        if (cameraDevice == null || !textureView.isAvailable() || mPreviewSize == null) {
            return;
        }
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
        RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                    (float) viewHeight / mPreviewSize.getHeight(),
                    (float) viewWidth / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        textureView.setTransform(matrix);
    }

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

Successfully merging this pull request may close these issues.

Preview size is not correctly calculated in Portrait mode
4 participants