安卓相机在横屏模式下拉伸

23

我正在编写的应用程序需要相机功能。因此,为了了解如何操作相机,我按照以下脚本进行操作:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html

我已经在清单文件中添加了这个活动,并将屏幕方向设置为横向模式。但问题是,当相机被横向持有时(例如我将Galaxy Tab P1000保持在横向位置),视图会被拉伸。更具体地说,在我的脚本中,我使用了Google制作的代码的精确副本。可以在android-sdk\samples\android-8\ApiDemos\src\com\example\android\apis\graphics\找到它。该文件本身称为CameraPreview。我真的不知道为什么屏幕看起来如此拉伸。当然,格式很奇怪而且不是正方形的,但是,当使用设备上安装的默认相机应用程序时,它根本不会变形。只有这个相机在我横向持有并稍微移动相机时才会变形。

enter image description here

enter image description here

我所做的是:我拿着我的Galaxy Tab拍摄一个物体(在这种情况下是笔记本电脑),然后用手机拍摄了我的Galaxy。在Galaxy上,我打开了我正在制作的应用程序中的相机屏幕。这适用于两张图片。一张我横向拿着,另一张我纵向拿着。这些照片有点不清晰,但您可以看到在横向照片中,相机变得非常宽。

4
这个问题只有我在全世界遇到吗? <: - Joey Roosing
我也遇到了这个问题... - Saty
这个问题是一个隐藏的宝石!我在搜索时遇到了很大的困难,已经用了谷歌中所有的关键词。这个问题救了我的命。 - Neon Warge
2个回答

22

我昨天面临了同样的问题。在研究“相机”源代码后,我找到了相机预览被拉伸的原因。

原因是:SurfaceView的纵横比(宽度/高度)必须与预览参数中使用的Camera.Size的纵横比相同。如果纵横比不同,你会得到一个被拉伸的图像。

所以,最快的解决方法是将SurfaceView设置为320px x 240px这样的大小 - 来自Parameters.getSupportedPreviewSizes()中支持的最小尺寸。

此外,你还可以查看相机标准应用程序源代码,它使用自定义布局来控制SurfaceView的大小(请参见PreviewFrameLayout.java中的onMeasure()函数)。

使用

git clone https://android.googlesource.com/platform/packages/apps/Camera.git

获取相机源代码。


1
在surfaceChanged中,您可以找到SurfaceView的高度和宽度,然后使用Camera参数对象上的getSupportedPreviewSizes来查找最接近的匹配项,并将SurfaceView设置为所需的可接受大小。请注意描述实际问题。 - Christopher Perry
我这样做,但不起作用。private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) { Camera.Size result = null; for (Camera.Size size : parameters.getSupportedPreviewSizes()) { if (size.width <= width && size.height <= height) { if (result == null) { result = size; } else { int resultArea = result.width * result.height; int newArea = size.width * size.height; if (newArea > resultArea) { result = size; } } } } return (result); } - gIrL
1
你的代码只是在寻找适合初始宽度和高度的最大预览尺寸。当然,你会遇到拉伸屏幕的问题,因为最大并不意味着“最佳宽高比”。你需要通过调整预览视图的宽度或高度来适应那个“最大”尺寸,使得比例=宽度/高度对于初始值(宽度、高度)和最终值(result.width、result.height)都相同。 - Lord

8
public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

        try {
            camera = Camera.open();

            camera.setDisplayOrientation(90);
            camera.setPreviewDisplay(holder);
            Camera.Parameters parameters = camera.getParameters();
            List<Size> sizes = parameters.getSupportedPictureSizes();
            parameters.setPictureSize(sizes.get(0).width, sizes.get(0).height); // mac dinh solution 0
            parameters.set("orientation","portrait");
            //parameters.setPreviewSize(viewWidth, viewHeight);
            List<Size> size = parameters.getSupportedPreviewSizes();
            parameters.setPreviewSize(size.get(0).width, size.get(0).height);
            camera.setParameters(parameters);
            camera.startPreview();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

您只需调用getSupportedPreviewSizes()并将其保存到List中即可:
List<Size> size = parameters.getSupportedPreviewSizes();
            parameters.setPreviewSize(size.get(0).width, size.get(0).height);
            camera.setParameters(parameters); 



camera.startPreview(); 

我希望这能对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接