相机在Android中,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像扭曲

时间:2014-02-10 02:59:20

标签: android image camera android-camera

在混合来自OpenGL和Android相机的视图时,图像会失真,以便在使用takepicture方法时获取两者的图像。我查了一下,发现相机图片设置为640X480,openGL视图和相机预览都设置为1280x720。

因此我将相机图片尺寸设置为1280x720,结果非常完美。但是我无法在代码中设置尺寸,因为每个Android设备都会有所不同,并且每个设备都必须从支持的尺寸列表中选择预览尺寸和图片尺寸的设置。

考虑到这里有三个变量,活动布局的屏幕尺寸,相机预览尺寸和图片尺寸,最好的方法是什么。

最好使用match_parent或fitXY作为FrameLayout大小,只能使用两个变量,预览大小和图片大小?

请注意预览尺寸和图片尺寸中的几种宽度和高度组合是相同的。例如1280 x 720同时存在于预览和图片中,是否总是会出现两种尺寸的匹配?

 List<Size> previewSizes = mCamera.getParameters().getSupportedPreviewSizes();

 List<Size> imageSizes = mCamera.getParameters().getSupportedPictureSizes();

 // layout in the activity that the cameraView will placed in
 int layoutWidth = frameLayout.getWidth();
 int layoutHeight = frameLayout.getHeight();

例如,在测量后的一个Android平板电脑中,这些是使用的3个变量的结果

作为测量结果的活动中布局视图组的大小

 1280 x 736

支持的图片尺寸

 320 x 240
 640 x 480
 1024 x 768
 1280 x 720 << best size in my example to use
 1280 x 768
 1280 x 920
 1600 x 1200
 2048 x 1536
 2560 x 1440
 2560 x 1536
 2560 x 1920  << native resolution of hardware camera

支持的预览尺寸

 176 x 144
 320 x 240
 352 x 288
 480 x 320
 480 x 368
 640 x 480
 800 x 480
 800 x 600
 864 x 480
 864 x 576
 960 x 540
 1280 x 720 << best size in my example to use
 1280 x 768
 1280 x 960

4 个答案:

答案 0 :(得分:14)

大多数情况下,但并非总是如此,图片宽高比和预览宽高比之间存在对应关系。您可以放心,至少其中一些是经典的4:3比率(例如640x480)。对16:9的支持也很普遍。

屏幕可能具有不同的宽高比。要正确填充相机图像,可以广泛接受添加黑色边距(在YouTube中使用相同的方法)。或者,您可以裁剪相机图像以填满整个屏幕。

请注意,屏幕尺寸(在各种设备的技术规格中报告)并不总是实际可用于图像显示。例如,系统菜单和标题栏等可以占用屏幕空间的份额。 沉浸式模式在某些设备上可用,其行为取决于系统版本。您可能会期待Android的未来发展,例如:第二个屏幕支持,将使游戏更加有趣

所以,你的具体问题的答案:

最好使用match_parent或fitXY作为FrameLayout大小,只能使用两个变量,即预览大小和图片大小? -

总是会出现两种尺寸都匹配的情况吗? - ,但这个尺寸可能不是最佳的。

即使您的相机支持不同的“宽”图片尺寸, 1280x720 预览和 2560x1440 图片也可能是最佳匹配,两者都恰好位于16:9。通常,小尺寸的图片质量并不比相同尺寸的预览好,所以如果1280x720是你真正需要的,你可以选择保存预览框。 p>

如果您可以放弃takePicture(),您的应用将会更加快速响应。

答案 1 :(得分:1)

可能的算法:

1)获得输出区域宽高比(=宽度/高度)

2)迭代支持的尺寸:

选择具有紧密纵横比的最大一个(例如+ - 5%) 如果没有任何接近或分辨率太低 - 只需将yor表面(绘制帧)设置为与支持的最大尺寸相同的纵横比,并将其置于父视图中心

Howewer,有预览尺寸和&amp;图片大小。如果您希望它们具有相同的宽高比 - 那么更好的选择是在1)中使用所选的图片尺寸宽高比。这样您可能必须在父视图中居中表面

希望有所帮助)

答案 2 :(得分:1)

我认为获得preview size, picture size的最佳方法是将相机设置为支持所有Android设备。这意味着您决定设置的preview size, picture size适合所有设备支持的流行格式,例如。是1280x720等。

如下面的代码,是ex。我用过的东西。

// start preview with new settings
    try {
        // set preview size and make any resize, rotate or
        // reformatting changes here
        Camera.Parameters parameters = mCamera.getParameters();

        for (Camera.Size size : parameters.getSupportedPictureSizes()) {
            // 640 480
            // 960 720
            // 1024 768
            // 1280 720
            // 1600 1200
            // 2560 1920
            // 3264 2448
            // 2048 1536
            // 3264 1836
            // 2048 1152
            // 3264 2176
            if (1600 <= size.width & size.width <= 1920) {
                parameters.setPreviewSize(size.width, size.height);
                parameters.setPictureSize(size.width, size.height);
                break;
            }
        }
        // Set parameters for camera
        CustomCamera.mCamera.setParameters(parameters);

        Camera.Size size = CustomCamera.mCamera.getParameters().getPictureSize();

        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        e.printStackTrace();
    }

Best size取决于相机MP。所以我认为如果使用Camera,应该使用默认值。

答案 3 :(得分:0)

我遇到了同样的问题,我在这里找到了这个很好的解决方案:http://www.java2s.com/example/android/camera/get-optimal-preview-size-by-width-and-height.html

我只需要在调用此函数之前通过交换宽度和高度来处理相机横向:

public static Camera.Size getOptimalPreviewSize(
        List<Camera.Size> sizes, int w, int h) {
    // Use a very small tolerance because we want an exact match.
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) w / h;
    if (sizes == null)
        return null;

    Camera.Size optimalSize = null;/*  w  w  w  .ja va  2 s .c  om*/

    // Start with max value and refine as we iterate over available preview sizes. This is the
    // minimum difference between view and camera height.
    double minDiff = Double.MAX_VALUE;

    // Target view height
    int targetHeight = h;

    // Try to find a preview size that matches aspect ratio and the target view size.
    // Iterate over all available sizes and pick the largest size that can fit in the view and
    // still maintain the aspect ratio.
    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    // Cannot find preview size that matches the aspect ratio, ignore the requirement
    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }

    return optimalSize;
}

...
// get optional sizes list
...

    if (SensorOrientation == 90 || SensorOrientation == 270) {
        // SWAP
        int tmp = mwidth;
        mwidth = mheight;
        mheight = tmp;
    }

    return getOptimalPreviewSize(sizes, mheight, mwidth);