Android中的相机,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像失真

Posted

技术标签:

【中文标题】Android中的相机,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像失真【英文标题】:Camera in Android, how to get best size, preview size, picture size, view size, image distorted 【发布时间】:2014-03-07 06:20:17 【问题描述】:

在使用 takepicture 方法时混合来自 OpenGL 和 android 相机的视图以获取两者的图像时图像失真。查了一下发现相机图片设置为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

【问题讨论】:

这会产生“未绑定到有效相机”错误吗? mCamera 是如何构建的? 【参考方案1】:

图片纵横比和预览纵横比之间通常存在对应关系,但并非总是如此。您可以放心,其中至少有一些是经典的 4:3 比例(例如 640x480)。对 16:9 的支持也很广泛。

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

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

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

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

是否总是两种尺寸都匹配? - ,但也许这个尺寸不是最佳的。

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

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

【讨论】:

【参考方案2】:

我认为获得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。所以我认为如果使用相机应该使用默认值。

【讨论】:

嗨伙计,Ur 代码有效,但是在 if 条件内我必须使用其他方式 if (size.width 嗨,它工作正常,但是当我在预览中使用此图像大小时,结果不同。它提供了我捕获的更多图像。 .getSupportedPictureSizes() 和 .getSupportedPreviewSizes() 可以不同(大多数情况下)【参考方案3】:

可能的算法:

1) 获取输出区域纵横比(=宽度/高度)

2) 遍历支持的尺寸:

选择长宽比接近的最大的(例如+-5%) 如果没有关闭或分辨率太低 - 只需使您的表面(您绘制框架的)与最大支持的尺寸具有相同的纵横比并将其在父视图中居中

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

希望有帮助)

【讨论】:

这是什么意思? ratio (=width/height) 2) 纵横比 = 宽/高。什么不明显? 我在你的“2)”中迷路了,你只是在列举你的观点。 ;) “选择最大的”现在不再总是可取的,因为这很容易产生 15 兆像素的图像,这对于大多数应用程序来说是多余的。 @anneb 取决于“最佳尺寸”的定义【参考方案4】:

我遇到了同样的问题,我在这里找到了这个出色的解决方案: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);

【讨论】:

这个高度和宽度是怎么选的?

以上是关于Android中的相机,如何获得最佳尺寸,预览尺寸,图片尺寸,视图尺寸,图像失真的主要内容,如果未能解决你的问题,请参考以下文章

android Camera 如何 获取最佳合适的尺寸

计算最佳相机预览尺寸的正确方法保持纵横比

如何在android中设置相机预览的大小

Android相机意图:如何获得全尺寸照片?

4:3 平板电脑上的 Android 相机预览纵横比

Android:拍摄的照片比预览大