当前位置: 首页 > 知识库问答 >
问题:

全屏相机显示/预览无法保持纵横比-图像倾斜、拉伸以适应屏幕

赵星华
2023-03-14

我开发了一个用于全屏显示相机预览的小应用程序。我使用的是摄像头API。

这是活动布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <!-- This is the container for the camera preview screen -->
    <FrameLayout android:id="@+id/camera_preview"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
</LinearLayout>

当设备在纵向时,显示器是垂直缩放的,以匹配设备屏幕的高度——所以宽高比不同于本地相机的宽高比。这两张图片更好地解释了我所说的:

第一幅图像是用本机相机设备拍摄的。第二幅图像是用我的应用程序制作的,相机全屏显示——图像倾斜、拉伸以适应屏幕。

我需要将相机预览设置为全屏,而不考虑getSupportedPreviewSizes()mehod给定的预览大小,并且不失真。有没有办法做到这一点?当相机预览处于全屏状态时,有没有办法保持适当的纵横比?我希望这可以通过操作系统自动完成,在保持纵横比的同时裁剪图像以匹配要求的分辨率,但这并没有发生。

我曾尝试将SurfaceView设置为比显示屏大(以下问题:将相机预览安装到比显示屏大的SurfaceView上),但在我的情况下,这并不正常,因为我正在拍摄快照(6帧/秒),而这些快照不是用户在屏幕上看到的(该帧包含所有相机预览,即使并非所有快照都在屏幕上可见)。

我在这里发布:https://www.dropbox.com/s/3d52xt8kazynsae/CameraFullScreen.7z?v=0mcn我做的整个项目。

任何想法/解决方案对我来说都非常重要。多谢了。

========================================================================

因ss1271更新答案:

我将稍微分析一下您在上面为三星Galaxy Ace II编写的分辨率。

I.屏幕分辨率:480x800-纵横比3:5=0,6

二,getSupportedPreviewSizes-我几乎可以肯定这些值来自后置摄像头。以下是这些分辨率的纵横比:

   2560x1920   - 0,75

   2560x1536   - 0,60

   2048x1536   - 0,75

   2048x1232   - 0,60

   960x720     - 0,75

   640x480     - 0,75

因此,您的方法将返回对应于2560x1536或2048x1232的size-这些具有与屏幕分辨率相同的宽高比,并且使用这些值不会扭曲图片。对我来说,问题是我不能使用这么大的分辨率,因为我每秒捕获6帧,这些需要以较低的分辨率保存。

我将在下面介绍三星S2设备的一些结果:

I.屏幕分辨率:480 x 800-纵横比3:5=0,6

二、后摄像头
a)<代码>getSupportedPreviewSizes:

800 / 480   - 480/800 = 0,60
800 / 450   - 450/800 = 0,56
720 / 480   - 0,66 
640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b) 。本机相机分辨率:

3264 / 2448  - 0,75  - not full screen
3264 / 1968  - 0,60  - FULL SCREEN (since has the same aspect ratio as device screen)
2048 / 1536  - 0,75  - not full screen
2048 / 1232  - 0,60  - FULL SCREEN (same aspect ratio as device screen)
800 / 480    - 0,60  - FULL SCREEN (same aspect ratio as device screen)
640 / 480    - 0, 75 - not full screen

三、 前摄像头
a)<代码>getSupportedPreviewSizes:

640 / 480   - 0,75
352 / 288   - 0,81
320 / 240   - 0,75
176 / 144   - 0,81

b) 。本机摄像头未全屏显示,我无法选择分辨率-该选项已禁用。

共有2个答案

松飞翮
2023-03-14

我在Camera2API中遇到了同样的问题,我使用了预览大小和设备纵横比来解决这个问题。您也可以使用摄影机API执行相同的操作。

龚志
2023-03-14

简而言之,您可以全屏进行相机预览,但是您需要自己在支持的预览尺寸中找到合适的尺寸,前提是您需要自定义相机预览。

对于你的问题,根据Android开发者-相机

如果要为相机预览设置特定大小,请按照上面的注释在surfaceChanged()方法中进行设置。设置预览大小时,必须使用getSupportedPreviewSizes()中的值。不要在setPreviewSize()方法中设置任意值。

除了getSupportedPreviewSizes()提供的大小之外,您似乎无法手动传递所需的大小。仔细检查手机摄像头支持的尺寸,您会发现支持的尺寸比例可能与屏幕比例不完全相同。

例如,三星Galaxy Ace II的屏幕分辨率为480x800,通过读取从getSupportedPreviewSizes()返回的Size,其摄像头支持:

2560x1920

2560x1536

2048x1536

2048x1232

960x720

640x480

如果你想在全屏上正确显示你的相机预览(没有拉伸),你需要计算、比较并应用这些支持的预览尺寸的合适比例。

找到合适预览大小的实现并不是那么复杂。执行此操作的常用方法如下:

    /**
     * Calculate the optimal size of camera preview
     * @param sizes
     * @param w
     * @param h
     * @return
     */
    private Size getOptimalSize(List<Size> sizes, int w, int h) {

        final double ASPECT_TOLERANCE = 0.2;        
        double targetRatio = (double) w / h;         
        if (sizes == null)             
            return null;          
        Size optimalSize = null;         
        double minDiff = Double.MAX_VALUE;          
        int targetHeight = h;          
        // Try to find an size match aspect ratio and size         
        for (Size size : sizes) 
        {             
//          Log.d("CameraActivity", "Checking size " + size.width + "w " + size.height + "h");            
            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 the one match the aspect ratio, ignore the requirement     

        if (optimalSize == null)
        {
            minDiff = Double.MAX_VALUE;             
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff)
                {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight); 
                }
            }
        }

        SharedPreferences previewSizePref;
        if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
            previewSizePref = getSharedPreferences("PREVIEW_PREF",MODE_PRIVATE);
        } else {
            previewSizePref = getSharedPreferences("FRONT_PREVIEW_PREF",MODE_PRIVATE);
        }

        SharedPreferences.Editor prefEditor = previewSizePref.edit();
        prefEditor.putInt("width", optimalSize.width);
        prefEditor.putInt("height", optimalSize.height);

        prefEditor.commit();

//      Log.d("CameraActivity", "Using size: " + optimalSize.width + "w " + optimalSize.height + "h");            
        return optimalSize;     
    }

你也可以做类似的事情来找到合适的相机尺寸(输出图片尺寸)。

注意:我从互联网上找到了上述代码的原始版本,并出于自己的目的进行了一些修改/优化。

请让我知道这是否适合你。

 类似资料:
  • 我有一个SurfaceView可以在我的Android应用程序中显示一个实时相机预览图像。SurfaceView覆盖了纵向屏幕的整个宽度和屏幕高度的一部分。 我试着设置了各种预览尺寸,所以预览有一个扭曲的纵横比,矮胖或者高高的骨瘦如柴。 我打印了显示实际预览显示大小和可用预览相机大小的调试,这样我就可以计算出纵横比错误。 我试穿了这个 阿尔卡特995,Android 4.0.4 三星Note 2,

  • 我有一个宽度为1900和高度为1000的图像,我使用的是和但我希望div高度与图像更改的高度相同。 示例: 在1366个屏幕中,图像将缩小尺寸以适应屏幕大小(宽度100%),因此,图像高度也将减小,因此我想获得该高度。 我试图做的是: HTML: CSS: 问题:vw是用滚动条宽度计算的,我想要没有,我可以使用宽度%而不是vw吗? 我接受别人的想法来做这件事,但我更喜欢使用CSS。

  • 我一直在努力在Android上制作我的自定义相机活动,但当旋转相机时,表面视图的纵横比会变得混乱。 在我的oncreate for the activity中,我设置了framelayout,它保存了显示相机参数的曲面视图。 然后,在曲面视图中,我设置要显示的相机参数 您可以看到,当手机旋转时,乐高男会变得更高、更瘦: 如何确保相机视图的纵横比正确?

  • 我想在一个容器中显示许多图像,但如果图像是横向的,它还不错,但如果图像是纵向的,当我插入它时,它会显示拉伸。它显示每一张图片景观,它不漂亮。我想显示每个图像,因为它的原始方向和容器的最大高度为415px。这是我的输出:风景图像纵向图像请帮助这是我的代码。

  • 使用CSS flex box模型,如何强制图像保持其纵横比? JS小提琴:http://jsfiddle.net/xLc2Le0k/2/ 请注意,为了填充容器的宽度,图像会拉伸或收缩。这很好,但是我们也能让它拉伸或收缩高度来保持图像比例吗? HTML CSS

  • 编辑:我应该提到的是,我知道纵横比公式:原始高度/原始宽度x新宽度=新高度,但是,我不知道如何正确地使用它,以我的优势。