Android中某些相机分辨率的不同捕获输出大小

Posted

技术标签:

【中文标题】Android中某些相机分辨率的不同捕获输出大小【英文标题】:Different capture output size on certain camera resolutions in Android 【发布时间】:2016-07-09 11:37:57 【问题描述】:

我正在使用 android Camera2 API 开发一个自定义相机应用程序,您可以在其中切换手机中可用的不同相机和视频分辨率。它还提供了拍摄平方 1:1 照片的可能性。为了拍摄方形照片,我拍摄了一张正常的 4:3 照片,然后对其进行裁剪以保持 1:1。 (所以 4032x3024 就是 3024x3024)。

我注意到在某些分辨率下拍摄 1:1 图片时出现问题,输出被略微裁剪(缩放)。这是用两种不同分辨率拍摄的同一张照片的结果:

The first picture was taken at 1944x1944

The second picture was taken at 3024x3024

我的 Nexus 5X 在 4:3 上支持 12MP、8MP、5MP 和 2MP。当我使用任何大于 5MP 的分辨率时,就会出现此问题。

我用来裁剪图像的方法如下:

ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
cropSquareImageByteArray(bytes);

cropSquareImageByteArray 方法:

public static byte[] cropSquareImageByteArray(byte[] bytes) 
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Bitmap dst = Bitmap.createBitmap(bitmap, 0, h - w, w, w);
    dst.compress(Bitmap.CompressFormat.JPEG, 98, bos);
    return bos.toByteArray();

我猜测裁剪的原因是 16:9 容器中的 4:3 图像。因为我在打电话的时候注意到了

    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

生成的位图输出的尺寸在 2MP 中为 1280x960 (4:3),在 5MP 中为 1600x1200 (4:3),但更大的分辨率为 1920x1080 (16:9),因此 4:3 图像被调整为16:9 位图,可能会导致裁剪。

我正在想办法解决这个问题。我还查看了这篇帖子Android 5.0 Wrong crop regions on preview surface and captured still image,但没有找到解决方案。

*edit: 我的 ImageReader 是这样配置的:

public void configureImageReader(Size pictureSizeValue, ImageReader.OnImageAvailableListener listener) 

    if (mImageReader == null) 
        mImageReader = ImageReader.newInstance(pictureSizeValue.getWidth(), pictureSizeValue.getHeight(),
                ImageFormat.JPEG, 2);
     
    mImageReader.setOnImageAvailableListener(listener, mBackgroundHandler);


pictureSizeValue 的值是我想要的输出。所以对于一个正方形的图像,它类似于 3024x3024。

【问题讨论】:

您的第二张图片应该是 3024x3024,看起来只有 1080x1080。所以是的,您似乎正在将 1920x1080 图像裁剪为正方形。所以 ImageReader 给你的尺寸与你想要的不同。你是如何配置 ImageReader 的?看起来该代码为更高分辨率选择了错误的大小。 我添加了 ImageReader 的代码。 ImageReader 的大小输入是我想要的确切输出,例如 3024x3024,适用于较小的分辨率。 啊,这就是问题所在。看我的回答。 【参考方案1】:

到某个点,相机设备会将您请求的尺寸四舍五入到支持的尺寸,以使相机预览设置更加灵活,但最高只能达到 1080p(通常保证预览的合理帧率)。

除此之外,您需要从设备提供的列表中实际选择一个支持的分辨率,否则您将只能向下舍入到 1080p。

可以使用StreamConfigurationMap.getOutputSizes() 查询相机支持的输出大小和格式。您需要扫描列表以找到符合您要求的尺寸以及与图像传感器的纵横比相匹配的纵横比(可通过activeArraySize 获得)

我也会仔细检查所有低于 1080p 的尺寸,以确保您确实得到了您想要的。舍入始终为较低的分辨率,以最大限度地降低性能和内存要求。

【讨论】:

以上是关于Android中某些相机分辨率的不同捕获输出大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中使用相机捕获自定义图像大小?

为啥使用相机意图捕获的图像会在 Android 上的某些设备上旋转?

android将相机捕获的图像的文件大小减小到小于500 kb

Android自动裁剪相机捕获的图像

使用android相机捕获图像后的空指针

提高 OpenCV 中的相机捕获分辨率