Подгонка предварительного просмотра камеры к SurfaceView большему, чем дисплей

У меня есть приложение для Android, которому требуется полноэкранный предварительный просмотр камеры независимо от размера предварительного просмотра, заданного getSupportedPreviewSizes(), без искажений. Я ожидаю, что это обрежет предварительный просмотр на некоторую величину по высоте или ширине, но меня это не касается. Причина, по которой я стремлюсь сделать это, заключается в том, что некоторые камеры Android (, например. Фронтальная камера Samsung Galaxy SII )не возвращает предварительный просмотр с тем же соотношением сторон, что и на дисплее, и поэтому ее необходимо растягивать и обрезать.

Можно ли полностью увеличить предварительный просмотр камеры до размера, превышающего размер дисплея? Можно увеличить SurfaceView больше, чем возвращаемые размеры в пикселях предварительного просмотра, просто установив параметры компоновки представления поверхности в соответствии с _родительским элементом, но это приводит к искажению в некотором направлении и возможно только до тех пор, пока предварительный просмотр не заполнит всю область. отображать. Похоже, это указывает на то, что предварительный просмотр вне экрана невозможен.аппаратное обеспечение (или ОС )ограничивают такое поведение.

Есть еще один вопрос по этой теме, но в этом вопросе утверждается, что невозможно создать SurfaceView больше, чем размеры экрана, что неверно, как я обнаружил при ведении журнала. Однако, похоже, дело в том, что предварительный просмотр камеры не может вырасти до полного размера огромного SurfaceView.

Моя попытка:

У меня есть относительный макет, внутри него FrameLayout, и внутри него я создаю SurfaceView. Ширина всей относительной компоновки установлена ​​ниже на уровне 635 dp, что ~вдвое превышает размер экрана устройства. FrameLayout соответствует этому размеру, как и SurfaceView (, добавленный программно позже )

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/camera_activity_layout"
    android:layout_width="635dp"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>

</RelativeLayout>

. Ниже приведен код, который получает и устанавливает размер предварительного просмотра. Здесь я хочу, чтобы предварительный просмотр камеры расширялся, чтобы заполнить весь FrameLayout (, удвоив ширину экрана ). Представление отображается и разрушается совершенно нормально, поэтому я удаляю код, не связанный с этим конкретным вопросом, потому что он отвлекает от основного вопроса и моей попытки легко и просто увеличить представление до большего -, чем -размера экрана.

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

   ...

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Camera.Parameters parameters = mCamera.getParameters();
        final DisplayMetrics dm = this.getResources().getDisplayMetrics();
            //getBestPreviewSize returns the best preview size, don't worry
            //but some devices do not return one for all camera matching the aspect ratio
        cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels);

        if (cameraSize!=null) {
            parameters.setPreviewSize(cameraSize.width, cameraSize.height);
            mCamera.setParameters(parameters);
        }

        FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams();

        frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT
        frameParams.height = LayoutParams.MATCH_PARENT;
        this.setLayoutParams(frameParams);

        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

            Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is ");
            Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is ");
        } catch (Exception e){
        }
    }
};

Я обеспокоен тем, что единственный способ преуспеть в этом начинании — каким-то образом отобразить поверхность openGL, но это очевидно может быть слишком медленным в полном цвете. Также неудобно, если предварительный просмотр камеры можно просто растянуть и обрезать.

Заранее спасибо за любые попытки решения.

23
задан Community 23 May 2017 в 12:02
поделиться