Android Camera 2预览尺寸和设备纵横比

Tru*_*NVT 10 mobile android

我正在我的项目中实现Camera 2 API.我正在使用TextureView和这些代码行设置相机全屏预览大小:

StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
Run Code Online (Sandbox Code Playgroud)

这似乎是设备支持的最大预览尺寸.我不确定这个尺寸是否适用于所有设备并且适合其设备的纵横比而不会被拉伸.有人知道吗?

Ron*_*tel 10

如果您的相机分辨率,纹理视图和设备的显示尺寸不同,则必须调整尺寸.为此,您必须将TextureView放在FrameLayout中.以下代码适用于具有各种显示分辨率的所有设备.

把你的显示器Dimetions如果你是在完全screen.Take预览int DSI_height,int DSI_width全局变量.

    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    DSI_height = displayMetrics.heightPixels;
    DSI_width = displayMetrics.widthPixels;
Run Code Online (Sandbox Code Playgroud)

从Camera2 API中选择所需的分辨率并分配给Size imageDimension,private Size imageDimension全局和使用

setAspectRatioTextureView(imageDimension.getHeight(),imageDimension.getWidth());
Run Code Online (Sandbox Code Playgroud)

并使用以下逻辑

private void setAspectRatioTextureView(int ResolutionWidth , int ResolutionHeight )
    {
        if(ResolutionWidth > ResolutionHeight){
            int newWidth = DSI_width;
            int newHeight = ((DSI_width * ResolutionWidth)/ResolutionHeight);
            updateTextureViewSize(newWidth,newHeight);

        }else {
            int newWidth = DSI_width;
            int newHeight = ((DSI_width * ResolutionHeight)/ResolutionWidth);
            updateTextureViewSize(newWidth,newHeight);
        }

    }

    private void updateTextureViewSize(int viewWidth, int viewHeight) {
        Log.d(TAG, "TextureView Width : " + viewWidth + " TextureView Height : " + viewHeight);
        textureView.setLayoutParams(new FrameLayout.LayoutParams(viewWidth, viewHeight));
    }
Run Code Online (Sandbox Code Playgroud)

  • 你能不能把整个代码贴出来..我不明白在哪里调用`setAspectRatioTextureView` (2认同)

ant*_*ori 6

可能存在这种方法会失败的边缘情况,但对于您的问题为什么我没有完美的答案。

相比之下,我有一个正确的方法来说明如何实现一个肯定会起作用的版本:

查看Camera 2Google API 演示,我发现了一些示例代码,它们应该对您有帮助,以确保它适合所有屏幕尺寸正确:

/**
 * Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
 * is at least as large as the respective texture view size, and that is at most as large as the
 * respective max size, and whose aspect ratio matches with the specified value. If such size
 * doesn't exist, choose the largest one that is at most as large as the respective max size,
 * and whose aspect ratio matches with the specified value.
 *
 * @param choices           The list of sizes that the camera supports for the intended output
 *                          class
 * @param textureViewWidth  The width of the texture view relative to sensor coordinate
 * @param textureViewHeight The height of the texture view relative to sensor coordinate
 * @param maxWidth          The maximum width that can be chosen
 * @param maxHeight         The maximum height that can be chosen
 * @param aspectRatio       The aspect ratio
 * @return The optimal {@code Size}, or an arbitrary one if none were big enough
 */
private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
        int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

    // Collect the supported resolutions that are at least as big as the preview Surface
    List<Size> bigEnough = new ArrayList<>();
    // Collect the supported resolutions that are smaller than the preview Surface
    List<Size> notBigEnough = new ArrayList<>();
    int w = aspectRatio.getWidth();
    int h = aspectRatio.getHeight();
    for (Size option : choices) {
        if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                option.getHeight() == option.getWidth() * h / w) {
            if (option.getWidth() >= textureViewWidth &&
                option.getHeight() >= textureViewHeight) {
                bigEnough.add(option);
            } else {
                notBigEnough.add(option);
            }
        }
    }

    // Pick the smallest of those big enough. If there is no one big enough, pick the
    // largest of those not big enough.
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else if (notBigEnough.size() > 0) {
        return Collections.max(notBigEnough, new CompareSizesByArea());
    } else {
        Log.e(TAG, "Couldn't find any suitable preview size");
        return choices[0];
    }
}
Run Code Online (Sandbox Code Playgroud)

来源

此外,您应该查看整个Camera2BasicFragment.javaAutoFitTextureView.java类以获得正确的实现。