配件相机preVIEW到SurfaceView比显示大相机、配件、SurfaceView、preVIEW

2023-09-12 10:57:25 作者:﹏挚爱·XX

我有一个需要全屏摄像头preVIEW无论无失真 getSupported previewSizes()给出的preVIEW大小的Andr​​oid应用。我希望这一定量无论是在高度或宽度裁剪preVIEW,但这不关我的事。我试图这样做的原因是因为某些安卓相机(如三星Galaxy SII的前置摄像头)不返回任何previews具有相同的宽高比显示,因此需要进行拉伸和裁剪。

I have an Android application that needs to fullscreen a camera preview regardless of the preview size given by getSupportedPreviewSizes() without distortion. I expect this to crop the preview by some amount in either the height or width, but this does not concern me. The reason I seek to do this is because certain android cameras (e.g. Samsung Galaxy SII front facing camera) do not return any previews with the same aspect ratio as the display, and therefore need to be stretched and clipped.

是否有可能完全成长相机preVIEW到视图比显示尺寸更大?有可能发展壮大的SurfaceView不是简单地返回preVIEW像素尺寸较大设定表面视图的布局PARAMS到match_parent,但这会导致失真在一些方向且仅是可能的,直到preVIEW填充的显示。这似乎表明的显​​示是不可能的外面previewing,和硬件(或OS)限制这种行为。

Is it possible to fully grow the camera preview to a view larger than the display size? It is possible to grow the SurfaceView larger than the preview pixel dimensions returned by simply setting the surface view's layout params to match_parent, but this results in distortion in some direction and only is possible up until the preview fills the display. This seems to indicate that previewing outside of the display is impossible, and the hardware (or OS) limits such behavior.

有另一个问题中的话题​​,但这个问题声称它是不可能创建一个SurfaceView大于屏幕尺寸,这是假的,因为我已经找到了记录。然而,似乎是情况是,摄像头preVIEW但是不能成长为一个巨大的SurfaceView的全尺寸。

There is another question on the topic, but that question claims it is not possible to create a SurfaceView greater than the screen dimensions, which is false, as I have found with logging. However, what seems to be the case is that camera preview however cannot grow to the full size of an enormous SurfaceView.

我的尝试:

我有一个相对布局,在它的FrameLayout,并在我创建一个SurfaceView。整个相对布局的宽度低于设定为635dp,这是〜设备的双屏幕尺寸。该赛事的FrameLayout这个尺寸和所以没有SurfaceView(编程方式添加更高版本)

I have a relative layout, within it a FrameLayout, and within that I create a SurfaceView. The width of the entire relative layout is set below at 635dp, which is ~double the device's screen size. The FrameLayout matches this sizing and so does the SurfaceView (added programmatically later)

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

以下是code,获取并设置preVIEW大小。在这里,我想使相机preVIEW扩大到充满整个的FrameLayout(双屏幕的宽度)。该视图显示了和自毁完全正常,所以我删除code没有涉及这个特殊的问题,因为它从一个至关重要的问题分散了,而我的尝试很容易和简单地认为生长到一定幅度超出显示尺寸。

The following is the code that gets and sets preview size. Here I want to make the camera preview expand to fill the entire FrameLayout (double the screen width). The view shows up and destructs totally normally so I am removing code not related to this particular question because it distracts from the essential question, and my attempt to easily and simply grow the view to some larger-than-display size.

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表面,但这apparently可能是全彩太慢。这也是一个疼痛如果照相机preVIEW可以简单地被拉伸和剪切。

I am concerned that the only way to succeed in this endeavor is to somehow render to an openGL surface, but this apparently might be too slow in full color. It is also a pain if the camera preview can simply be stretched and clipped.

在此先感谢在解决方案的任何企图。

Thanks in advance to any attempts at the solution.

推荐答案

好吧,我知道这是非常晚的一个答案,但它是可能的。下面是从Android SDK示例code。要查看的code,其余实行此下载Android SDK的样品,然后转到样品/ Android为10(我使用的,可以尝试任何你想要的目标)/ ApiDemos / src目录/ COM /例子/安卓/原料药/显卡/摄像头preview.java

Ok, I know this is very late as an answer but it is possible. Below is code from the Android SDK sample. To see the rest of the code to implement this download the android sdk samples and go to Samples/android-10(one I used, could try whichever you want to target)/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java

class PreviewSurface extends ViewGroup implements SurfaceHolder.Callback {
...
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed && getChildCount() > 0) {
        final View child = getChildAt(0);

        final int width = r - l;
        final int height = b - t;

        int previewWidth = width;
        int previewHeight = height;
        if (mPreviewSize != null) {
            previewWidth = mPreviewSize.width;
            previewHeight = mPreviewSize.height;
        }

        // Center the child SurfaceView within the parent.
        if (width * previewHeight > height * previewWidth) {
            final int scaledChildWidth = previewWidth * height / previewHeight;
            child.layout((width - scaledChildWidth) / 2, 0,
                    (width + scaledChildWidth) / 2, height);
        } else {
            final int scaledChildHeight = previewHeight * width / previewWidth;
            child.layout(0, (height - scaledChildHeight) / 2,
                    width, (height + scaledChildHeight) / 2);
        }
    }
}
}

这code是为了适应preVIEW到最小尺寸(即不搞乱aspcect比)中心,对其他方面的黑条。但是,如果你把&GT; &LT; ,而不是你会实现你想要的。例如:

this code is intended to fit the preview to the smallest dimension (that doesn't mess up the aspcect ratio) and center to have black bars on the other dimension. But if you flip the > to be < instead you will achieve what you want. Ex:

if (width * previewHeight < height * previewWidth) {...