Android:拍摄的照片比预览大

Posted

技术标签:

【中文标题】Android:拍摄的照片比预览大【英文标题】:Android: Taken photo is bigger than the preview 【发布时间】:2015-01-13 12:06:09 【问题描述】:

我正在尝试使用相机 api 直接拍摄照片,但这是我得到的预览:

& 这是调用takePicture() 后拍摄的图像,比预览本身大:

(注意:我裁剪了前两张照片的高度以增强问题的可读性,并保持宽度不变)

我正在使用这个实用方法在开始相机预览之前选择最佳的最佳预览尺寸:

public static Camera.Size getBestAspectPreviewSize(int displayOrientation,
                                                   int width,
                                                   int height,
                                                   Camera.Parameters parameters) 
    double targetRatio = (double) width / height;
    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;
    if (displayOrientation == 90 || displayOrientation == 270) 
        targetRatio = (double) height / width;
    
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
    Collections.sort(sizes,
            Collections.reverseOrder(new SizeComparator()));
    for (Camera.Size size : sizes) 
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) < minDiff) 
            optimalSize = size;
            minDiff = Math.abs(ratio - targetRatio);
        
        if (minDiff < 0.0d) 
            break;
        
    
    return (optimalSize);

&这个方法可以选择合适的图片尺寸:

public static Camera.Size getBiggestSafePictureSize(Camera.Parameters parameters) 
    Camera.Size result = null;
    long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    long availableMemory = Runtime.getRuntime().maxMemory() - used;
    for (Camera.Size size : parameters.getSupportedPictureSizes()) 
        int newArea = size.width * size.height;
        long neededMemory = newArea * 4 * 4; // newArea * 4 Bytes/pixel * 4 needed copies of the bitmap (for safety :) )
        if (neededMemory > availableMemory)
            continue;
        if (result == null) 
            result = size;
         else 
            int resultArea = result.width * result.height;
            if (newArea > resultArea) 
                result = size;
            
        
    
    return (result);

&这是布局中的相机预览元素:

<FrameLayout
    android:layout_
    android:layout_
    android:id="@+id/cameraPreview"></FrameLayout>

& 我正在关注 the official documentation 自己创建相机预览

那么,如何强制相机预览显示将要拍摄的确切照片?

【问题讨论】:

【参考方案1】:

终于找到了:)

据此answer & 我引用:

虽然典型的相机是 4:3 纵横比,但预览也可能以 5:3 和 16:9 的比例提供,这似乎是通过实际扩展图像的水平场来实现的查看...

所以我们需要找到预览尺寸和图片尺寸,两者都具有 4:3 纵横比,以便能够利用相机的全角度,所以我像这样更改了我的代码:

public static Camera.Size determineBestPreviewSize(Camera.Parameters parameters) 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
    return determineBestSize(sizes);


public static Camera.Size determineBestPictureSize(Camera.Parameters parameters) 
    List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
    return determineBestSize(sizes);


protected static Camera.Size determineBestSize(List<Camera.Size> sizes) 
    Camera.Size bestSize = null;
    long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    long availableMemory = Runtime.getRuntime().maxMemory() - used;
    for (Camera.Size currentSize : sizes) 
        int newArea = currentSize.width * currentSize.height;
        long neededMemory = newArea * 4 * 4; // newArea * 4 Bytes/pixel * 4 needed copies of the bitmap (for safety :) )
        boolean isDesiredRatio = (currentSize.width / 4) == (currentSize.height / 3);
        boolean isBetterSize = (bestSize == null || currentSize.width > bestSize.width);
        boolean isSafe = neededMemory < availableMemory;
        if (isDesiredRatio && isBetterSize && isSafe) 
            bestSize = currentSize;
        
    
    if (bestSize == null) 
        return sizes.get(0);
    
    return bestSize;

【讨论】:

这里似乎是非常宝贵的信息!【参考方案2】:

您应该对parameters.getSupportedPictureSizes() 返回的大小运行相同的循环,而不是依赖默认图片大小。此外,我宁愿寻找最佳对应的预览/图片尺寸对,如果此纵横比与cameraPreview 布局的纵横比不匹配,则让图片在屏幕上进行裁剪。

【讨论】:

好吧,我已经编辑了问题以添加我用于选择图片大小的方法。但我认为这都是关于预览的,因为它没有像拍摄的照片那样显示相机的全部可能角度。我试图将我的预览表面与 Instagram 中的进行比较,而 Instagram 的预览显示的是全角度,就像我的代码拍摄的图片一样,所以问题出在我的预览中 您的设备有哪些尺寸?它们的纵横比是否相同? 嗯,我使用的方法在 LG-G2 上给了我以下信息:预览尺寸为 1776X1080,图片尺寸为 3264X2448 但是,正如我告诉你的,当我在相同的 2 台设备上打开 Instagram 时,它会以更大的摄像头角度打开,显示预览,就像我的应用程序拍摄的照片一样,所以问题出在我的预览! 请选择适合 4:3 的预览尺寸,而不是相反。

以上是关于Android:拍摄的照片比预览大的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Android中的Camera2 API在不预览的情况下拍摄多张照片?

Android相机照片预览正在逆转

在 Android 相机中拍摄的照片比预期的要小

Android - 拍摄照片

Android:保存用户使用相机拍摄的照片

Android相机第二次拍摄失败