简体   繁体   English

Android相机预览肖像比例

[英]Android camera preview portrait scale

Please help to make proper configuration of Android camera (testing on HTC Desire 2.3.3) to preview from camera in rotated (portrait) mode. 请帮助正确配置Android摄像头(在HTC Desire 2.3.3上进行测试),以便在旋转(纵向)模式下从摄像头进行预览。 Preview have to take less than a half of screen, it width have to be equal to device width, and scale have to be set dynamically according to camera aspect ratio. 预览必须占用不到一半的屏幕,宽度必须等于设备宽度,并且必须根据相机纵横比动态设置比例。 My current code: 我目前的代码:

public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback {
…
public void surfaceCreated(SurfaceHolder holder) {
try {
    if (camera != null) {
                try {
                    camera.stopPreview();
                } catch (Exception ignore) {
                }
                try {
                    camera.release();
                } catch (Exception ignore) {
                }
                camera = null;
            }

            camera = Camera.open();             
            camera.setPreviewDisplay(holder);
        } catch (Exception ex) {
            try {
                if (camera != null) {
                    try {
                        camera.stopPreview();
                    } catch (Exception ignore) {
                    }
                    try {
                        camera.release();
                    } catch (Exception ignore) {
                    }
                    camera = null;
                }
            } catch (Exception ignore) {    
            }
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            if (camera != null) {
                try {
                    camera.stopPreview();
                } catch (Exception ignore) {
                }
                try {
                    camera.release();
                } catch (Exception ignore) {
                }
                camera = null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        try {
            Camera.Parameters parameters = camera.getParameters();
            float bff = 0;
            try {
                List<Camera.Size> supportedSizes = null;

                //maximize supported resizes, TODO remove as hardcode
                w*=1.5;
                h*=1.5;

                // On older devices (<1.6) the following will fail
                // the camera will work nevertheless
                supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);

                // preview form factor
                float ff = (float) w / h;
                Log.d("TAG", "Screen res: w:" + w + " h:" + h
                        + " aspect ratio:" + ff);

                // holder for the best form factor and size                 
                int bestw = 0;
                int besth = 0;
                Iterator<Camera.Size> itr = supportedSizes.iterator();

                // we look for the best preview size, it has to be the closest
                // to the
                // screen form factor

                while (itr.hasNext()) {
                    Camera.Size element = itr.next();
                    // current form factor
                    float cff = (float) element.width / element.height;
                    // check if the current element is a candidate to replace
                    // the best match so far
                    // current form factor should be closer to the bff
                    // preview width should be less than screen width
                    // preview width should be more than current bestw
                    // this combination will ensure that the highest resolution
                    // will win
                    Log.d("TAG", "Candidate camera element: w:"
                            + element.width + " h:" + element.height
                            + " aspect ratio:" + cff);
                    if ((ff - cff <= ff - bff) && (element.width <= w)
                            && (element.width >= bestw)) {
                        bff = cff;
                        bestw = element.width;
                        besth = element.height;
                    }
                }
                Log.d("TAG", "Chosen camera element: w:" + bestw + " h:"
                        + besth + " aspect ratio:" + bff);
                // Some Samsung phones will end up with bestw and besth = 0
                // because their minimum preview size is bigger then the screen
                // size.
                // In this case, we use the default values: 480x320
                if ((bestw == 0) || (besth == 0)) {
                    Log.d("Mixare", "Using default camera parameters!");
                    bestw = 480;
                    besth = 320;
                }               
                parameters.setPreviewSize(bestw,besth);
            } catch (Exception ex) {
                parameters.setPreviewSize(480,320);

                bff=1.5f;
            }
            makeResizeForCameraAspect(bff);                     
            camera.setDisplayOrientation(90);//only Android 2.2 and later
            camera.setParameters(parameters);               
            camera.startPreview();
        } catch (Exception ex) {
            Log.e(TAG,"",ex);
        }
    }

    private void makeResizeForCameraAspect(float cameraAspectRatio){
        LayoutParams layoutParams=this.getLayoutParams();
        int matchParentWidth=this.getWidth();           
        int newHeight=(int)(matchParentWidth/cameraAspectRatio);
        if(newHeight!=layoutParams.height){
            layoutParams.height=newHeight;
            layoutParams.width=matchParentWidth;    
            this.setLayoutParams(layoutParams);
            this.invalidate();
        }
    }
}

Activity layout: 活动布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >  
    <org.mixare.CameraSurface
        android:id="@+id/camera_surface"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_alignParentTop="true"

         />
    <!--CameraSurface layout_height will be changed during it's loading process -->
</RelativeLayout>

AndroidManifest configured to portrait: AndroidManifest配置为肖像:

  <activity android:label="@string/app_name" android:name=".MixView" 
    android:screenOrientation="portrait"  
    android:launchMode="singleTop" >

actual images: 实际图片:

在此输入图像描述 - device rotated portrait - 设备旋转肖像

在此输入图像描述 - device rotated landscape - 设备旋转景观

Found in the same topics: Android - Camera preview is sideways , Android camera rotate , but I've got same result with their code 在相同的主题中找到: Android - 相机预览是侧面的Android相机旋转 ,但我的代码有相同的结果

And here you could see wrong proportions of the image. 在这里你可以看到错误的图像比例。 How make to show in proper proportions rotated & scaled camera preview? 如何以适当的比例显示旋转和缩放的相机预览?

Parts of code were taken from Mixare Open Source project, http://www.mixare.org/ 部分代码取自Mixare开源项目, http://www.mixare.org/

I know I am too late to answer this, but this issue can be fixed by setting display orientation of camera to 90 degrees ie by adding following line after camera.open() in SurfaceCreated method of CameraSurface class 我知道我来不及回答这个问题,但是这个问题可以通过将摄像机的显示方向设置为90度来修复,即通过在CameraSurface类的SurfaceCreated方法中的CameraSurface camera.open()之后添加以下行来CameraSurface

camera.setDisplayOrientation(90);

Hope this helps others having the same issue. 希望这有助于其他人遇到同样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM