Android Camera2预览被拉伸

如何解决Android Camera2预览被拉伸

我正在尝试学习Camera2 API,并且已经构建了一个简单的相机应用程序仅用于拍照,但是我面临的问题是预览在某些分辨率下会被拉伸。我浏览了许多不同的帖子,所有这些帖子都暗示我的宽高比可能是错误的,但是我使用了Google推荐的AutoFitTextureView,但正确的宽高比仍然使我的预览被拉伸了。我从playstore下载了一些开源相机应用程序,其中很多也与我的前置相机(EXCEPT OPEN CAMERA)存在相同的问题,但有趣的是我在另一台设备上使用了相同的应用程序,并且预览效果绝对完美。所以最后我决定用不同的分辨率测试我的应用程序并观察结果,但是我找不到任何模式可以帮助任何人使我从中受益吗?

my device display size is 720x1280
Front camera results: 
SurfaceTexture        AutoFitTextureView         Result
buffer size           size       
2576x1932             720x960                    Normal
2560x1440             720x1280                   Normal
2048x1536             720x960                    Normal
2048x1152             720x1280                   Normal
1920x1920             720x720                    Normal
1920x1080             720x1280                   Normal
1440x1080             720x960                    Horizontally Stretched
1280x720              720x1280                   Horizontally Stretched
1072x1072             720x720                    Normal
960x720               720x960                    Normal
720x480               720x1080                   Horizontally Stretched
640x480               720x960                    Horizontally Stretched
352x288               720x880                    Normal
320x240               720x960                    Normal
256x144               720x1280                   Horizontally Stretched
176x144               720x880                    Normal

解决方法

Camera2作为初学者很难学习。考虑使用功能最强大的相机库。这是我发现的最好的一个:https://camerakit.io/docs。这真的很容易,它将解决您现在面临的所有问题。
(请注意,我不是这个项目的所有者,无论如何我都不会推广它。我已经尝试使用camera2 API,但确实很难,这就是为什么我建议了一个更简单的解决方案。

,

这实际上可能是设备错误-摄像头实现无法从完整的传感器尺寸进行缩放。这种情况通常发生在大多数应用程序不使用的异常大小上。

在您的情况下,相机管线的某些部分可能会将1440x1080视为1920x1080,从而导致拉伸。有时,可以通过添加第二种输出(例如,JPEG)以不同的分辨率(有时甚至是相同的分辨率)来“修复”。

当然,您的代码(或AutoFitTextureView)中仍然可能存在逻辑错误。但是,这些很难为您提供有用的建议-这是检查所有布局并逐步缩放数学的问题。

您还可以尝试使用Google的官方相机支持库CameraX。它处于测试阶段,可以很好地用于基本用例,例如预览,静止图像捕获和图像分析。

,

他们的关键是在您渲染预览的 TextureView 上设置正确的变换。 TextureView 的宽度和高度设置为匹配其父布局。

TextureView textureView;

void setTextureTransform(CameraCharacteristics characteristics) {
    Size previewSize = getPreviewSize(characteristics);
    int width = previewSize.getWidth();
    int height = previewSize.getHeight();
    int sensorOrientation = getCameraSensorOrientation(characteristics);
    // Indicate the size of the buffer the texture should expect
    textureView.getSurfaceTexture().setDefaultBufferSize(width,height);
    // Save the texture dimensions in a rectangle
    RectF viewRect = new RectF(0,textureView.getWidth(),textureView.getHeight());
    // Determine the rotation of the display
    float rotationDegrees = 0;
    try {
        rotationDegrees = (float)getDisplayRotation();
    } catch (Exception ignored) {
    }
    float w,h;
    if ((sensorOrientation - rotationDegrees) % 180 == 0) {
        w = width;
        h = height;
    } else {
        // Swap the width and height if the sensor orientation and display rotation don't match
        w = height;
        h = width;
    }
    float viewAspectRatio = viewRect.width()/viewRect.height();
    float imageAspectRatio = w/h;
    final PointF scale;
    // This will make the camera frame fill the texture view,if you'd like to fit it into the view swap the "<" sign for ">"
    if (viewAspectRatio < imageAspectRatio) {
        // If the view is "thinner" than the image constrain the height and calculate the scale for the texture width
        scale = new PointF((viewRect.height() / viewRect.width()) * ((float) height / (float) width),1f);
    } else {
        scale = new PointF(1f,(viewRect.width() / viewRect.height()) * ((float) width / (float) height));
    }
    if (rotationDegrees % 180 != 0) {
        // If we need to rotate the texture 90º we need to adjust the scale
        float multiplier = viewAspectRatio < imageAspectRatio ? w/h : h/w;
        scale.x *= multiplier;
        scale.y *= multiplier;
    }

    Matrix matrix = new Matrix();
    // Set the scale
    matrix.setScale(scale.x,scale.y,viewRect.centerX(),viewRect.centerY());
    if (rotationDegrees != 0) {
        // Set rotation of the device isn't upright
        matrix.postRotate(0 - rotationDegrees,viewRect.centerY());
    }
    // Transform the texture
    textureView.setTransform(matrix);
}

int getDisplayRotation() {
    switch (textureView.getDisplay().getRotation()) {
        case Surface.ROTATION_0:
        default:
            return 0;
        case Surface.ROTATION_90:
            return  90;
        case Surface.ROTATION_180:
            return  180;
        case Surface.ROTATION_270:
            return 270;
    }
}

Size getPreviewSize(CameraCharacteristics characteristics) {
    StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    Size[] previewSizes = map.getOutputSizes(SurfaceTexture.class);
    // TODO: decide on which size fits your view size the best
    return previewSizes[0];
}

int getCameraSensorOrientation(CameraCharacteristics characteristics) {
    Integer cameraOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
    return (360 - (cameraOrientation != null ? cameraOrientation : 0)) % 360;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?