android相机预览错误的宽高比

der*_*itz 17 android android-camera

我根据教程创建了一个相机应用程序.我使用的预览类来自api-Demos"CameraPreview".我从这里添加了一个修改(预览总是旋转90°).这就是我设置预览大小的方法:

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

    if (display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(mPreviewSize.height, mPreviewSize.width);
        mCamera.setDisplayOrientation(90);
    }

    if (display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    }

    if (display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(mPreviewSize.height, mPreviewSize.width);
    }

    if (display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setDisplayOrientation(180);
    }
    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

    requestLayout();

    mCamera.setParameters(parameters);
    mCamera.startPreview();
}
Run Code Online (Sandbox Code Playgroud)

但预览显示的宽高比错误.是因为上面的代码还是因为我使用的布局?:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
    android:id="@+id/button_capture"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" 
    android:text="@string/capture" />

<FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="100dp"
    android:layout_height="match_parent"/>
Run Code Online (Sandbox Code Playgroud)

那么如何获得正确的宽高比?提前致谢.

PS我读了答案:Android相机预览看起来很奇怪 但这对我不起作用.

Hen*_*ric 23

尝试添加此功能来更改预览尺寸:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.05;
    double targetRatio = (double) w/h;

    if (sizes==null) return null;

    Camera.Size optimalSize = null;

    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    // Find size
    for (Camera.Size size : sizes) {
        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);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}
Run Code Online (Sandbox Code Playgroud)

并根据这些优化值设置尺寸:

List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);

parameters.setPreviewSize(optimalSize.width, optimalSize.height);
Run Code Online (Sandbox Code Playgroud)

我希望这有效:)

最好的祝福

Henric


gts*_*ouk 5

以下代码修改相机预览容器的宽度/高度以匹配相机预览的宽高比.

    Camera.Size size = camera.getParameters().getPreviewSize();

    //landscape
    float ratio = (float)size.width/size.height;

    //portrait
    //float ratio = (float)size.height/size.width;

    preview = (FrameLayout) findViewById(R.id.camera_preview);

    int new_width=0, new_height=0;
    if(preview.getWidth()/preview.getHeight()<ratio){
        new_width = Math.round(preview.getHeight()*ratio);
        new_height = cameraPreview.getHeight();
    }else{
        new_width = preview.getWidth();
        new_height = Math.round(preview.getWidth()/ratio);
    }
    preview.setLayoutParams(new FrameLayout.LayoutParams(new_width, new_height));
Run Code Online (Sandbox Code Playgroud)