安卓相机设置setDisplayOrientation无效

7

我正在进行一个Android摄像头项目。 我的问题是相机的setDisplayOrientation方法无法正常工作,并且我的相机预览在表面上始终是横向的。 我希望在SurfaceView上获得期望的竖向相机预览。 我正在使用三星Galaxy Y(Android 2.3.5),我的活动代码如下:

import java.io.IOException;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class AndroidCamera extends Activity implements SurfaceHolder.Callback{

 Camera camera;
 SurfaceView surfaceView;
 SurfaceHolder surfaceHolder;
 boolean previewing = false;;

 String stringPath = "/sdcard/samplevideo.3gp";

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       Button buttonStartCameraPreview = (Button)findViewById(R.id.startcamerapreview);
       Button buttonStopCameraPreview = (Button)findViewById(R.id.stopcamerapreview);

       getWindow().setFormat(PixelFormat.UNKNOWN);
       surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
       surfaceHolder = surfaceView.getHolder();
       surfaceHolder.addCallback(this);
       surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

       buttonStartCameraPreview.setOnClickListener(new Button.OnClickListener(){

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    if(!previewing){
     camera = Camera.open();
     if (camera != null){
      try {
       camera.setDisplayOrientation(90);
       camera.setPreviewDisplay(surfaceHolder);
       camera.startPreview();
       previewing = true;
      } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
    }
   }});

       buttonStopCameraPreview.setOnClickListener(new Button.OnClickListener(){

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    if(camera != null && previewing){
     camera.stopPreview();
     camera.release();
     camera = null;

     previewing = false;
    }
   }});

   }



 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
   int height) {
  // TODO Auto-generated method stub

 }

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

 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
  // TODO Auto-generated method stub

 }
}

以下是我的问题:

在此输入图片描述

是否有人可以提供任何代码或教程链接?感谢您宝贵的时间。


它在其他手机上能用吗?还是你只试过这一个? - sheetal
@sheetal 我只尝试过这一个。 - Dinesh
4个回答

6
最终我找到了解决方案,并找到了相机预览的SurfaceView代码:
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Build;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    private static boolean DEBUGGING = true;
    private static final String LOG_TAG = "CameraPreviewSample";
    private static final String CAMERA_PARAM_ORIENTATION = "orientation";
    private static final String CAMERA_PARAM_LANDSCAPE = "landscape";
    private static final String CAMERA_PARAM_PORTRAIT = "portrait";
    protected Activity mActivity;

    protected List<Camera.Size> mPreviewSizeList;
    protected List<Camera.Size> mPictureSizeList;
    protected Camera.Size mPreviewSize;
    protected Camera.Size mPictureSize;


    public CameraPreview(Context context, Camera camera) {
        super(context);

        mActivity=(Activity)context;
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("CameraView", "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
           // mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            Camera.Parameters cameraParams = mCamera.getParameters();
            boolean portrait = isPortrait();
            configureCameraParameters(cameraParams, portrait);

            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d("CameraView", "Error starting camera preview: " + e.getMessage());
        }
    }

    public void onPause() {
        mCamera.release();
        mCamera = null;
    }


    protected void configureCameraParameters(Camera.Parameters cameraParams, boolean portrait) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
            if (portrait) {
                cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
            } else {
                cameraParams.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
            }
        } else { // for 2.2 and later
            int angle;
            Display display = mActivity.getWindowManager().getDefaultDisplay();
            switch (display.getRotation()) {
                case Surface.ROTATION_0: // This is display orientation
                    angle = 90; // This is camera orientation
                    break;
                case Surface.ROTATION_90:
                    angle = 0;
                    break;
                case Surface.ROTATION_180:
                    angle = 270;
                    break;
                case Surface.ROTATION_270:
                    angle = 180;
                    break;
                default:
                    angle = 90;
                    break;
            }
            Log.v(LOG_TAG, "angle: " + angle);
            mCamera.setDisplayOrientation(angle);
        }

        cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
        if (DEBUGGING) {
            Log.v(LOG_TAG, "Preview Actual Size - w: " + mPreviewSize.width + ", h: " + mPreviewSize.height);
            Log.v(LOG_TAG, "Picture Actual Size - w: " + mPictureSize.width + ", h: " + mPictureSize.height);
        }

        mCamera.setParameters(cameraParams);
    }


    public boolean isPortrait() {
        return (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
    }
}

需要最低的SDK版本为2.3或更高


2

如果您想旋转预览输出,请尝试以下方法:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {            
        if (isPreviewRunning)
        {
            mCamera.stopPreview();
        }

        Parameters parameters = mCamera.getParameters();
        Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

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

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

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

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

        mCamera.setParameters(parameters);
        previewCamera();                      
    }

1
还有,请检查手机设置中是否选中了“自动旋转屏幕”选项(设置>显示或屏幕-取决于Android版本)。
我花了很长时间才弄明白。如果没有选择,则应用程序中的相机方向可能会被忽略。

1

对于较低的API级别,您可以使用:

private void setCameraDisplayOrientationAPI8(){
        //Sets the camera right Orientation.
        //Special void for API 8 build.
        //This void should be called before calling camera.setParameters(cameraParameters).
        if (activeActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
        {   
            camera.setDisplayOrientation(90);
        }
        if (activeActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
        {                               
            camera.setDisplayOrientation(180);
        }
    }

只需在您的surfaceChanged函数中调用setCameraDisplayOrientationAPI8();

此外:

private void setCameraDisplayOrientation() {
        //Sets the camera right Orientation.
        //IMPORTANT!! This code is available only for API Level 9 build or greater.
        if (mApiLvl<9){
            Log.d(TAG, "setCameraDisplayOrientation ERROR: This code is available only for API Level 9 build or greater.");
            return;
        }
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraIndex, info);
        int rotation = activeActivity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }

希望这能有所帮助。

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