为什么相机的实时预览会旋转90度?

时间:2013-03-03 14:24:35

标签: java android eclipse android-layout android-camera

我写了一个相机应用程序,但是当我想要显示相机的实时预览时(拍照前),预览旋转了90度!这是我的相机活动的代码:

public class CameraActivity extends Activity{
    public static final int MEDIA_TYPE_IMAGE = 1 ;
    private Camera mCamera;
    private CameraPreview mPreview;
    Uri photoPath ;
    protected void onStop()
    {
        super.onStop();
        mCamera.release();
    }
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        ViewGroup.LayoutParams previewParam = preview.getLayoutParams() ;
        Parameters cameraParam =  mCamera.getParameters() ;
        double ratio = (double)cameraParam.getPictureSize().height / (double)cameraParam.getPictureSize().width  ;
      //  previewParam.height=  cameraParam.getPictureSize().height / 5 ;
       // previewParam.width = cameraParam.getPictureSize().width / 5  ;
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        try
        {
            display.getSize(size);
        }
        catch(java.lang.NoSuchMethodError ignore)
        {
            size.x = display.getWidth(); 
            size.y = display.getHeight() ;
        }
        int width = size.x;
        int height = size.y;
        previewParam.width =  width;
        previewParam.height = (int)(previewParam.width * ratio) ;
       // preview.setLayoutParams(previewParam) ;
        preview.addView(mPreview);
    }

    //Camera Classes here
    private final static String TAG = "Navid";
    public static Camera getCameraInstance() 
    {
        Camera c = null ;
        try
        {
            c = Camera.open() ;
        }
        catch(Exception e)
        {
        }
        return c ;
    }
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
    {
        private SurfaceHolder mHolder ;
        private Camera mCamera; 
        public CameraPreview(Context context , Camera camera)
        {
            super(context) ;
            mCamera = camera ;

            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        public void surfaceCreated(SurfaceHolder holder)
        {
            try
            {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            }
            catch(IOException e)
            {
                Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
            }
        }
        public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
        {   
        }
        public void surfaceDestroyed(SurfaceHolder holder)
        {           
        }
    }
    private static File getOutputMediaFile(int type){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                  Environment.DIRECTORY_PICTURES), "MyCameraApp");
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("MyCameraApp", "failed to create directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
            "IMG_"+ timeStamp + ".jpg");
        }else {
            return null;
        }
        return mediaFile;
    }
    //save the picture here
    private PictureCallback mPicture = new PictureCallback() {

    //  public final static int  MEDIA_TYPE_IMAGE = 1 ;
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            photoPath = Uri.fromFile(pictureFile);
            if (pictureFile == null){
                Log.d("Errore Doorbin", "Error creating media file, check storage permissions: ");
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
                // these lines are for the gallery to scan the SDCard manually
                File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES), "MyCameraApp");
                    sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                        Uri.parse("file://"+ mediaStorageDir)));
              // photoPath = Uri.fromFile(mediaStorageDir) ;
               /* MediaScannerConnection.scanFile(CameraActivity.this,
                        new String[] { fos.toString() }, null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                        // code to execute when scanning is complete
                    }
               });*/
               // fos.close();
            } catch (FileNotFoundException e) {
                Log.d("Errore Doorbin", "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d("Errore Doorbin", "Error accessing file: " + e.getMessage());
            }
            catch (Exception e)
            {
                Log.d("Errore Doorbin", "errore Kolli dade!" + e.getMessage()) ;
            }
        }
    };
    public void capture(View v)
    {
        //mCamera.takePicture(null, null, mPicture);
        //mCamera.release(); 
        //mCamera = getCameraInstance() ;
        //mCamera.startPreview();

        TakePictureTask takePicture = new TakePictureTask() ;
        takePicture.execute() ;
    }
    public void accept(View v)
    {
        Intent data = new Intent() ;
        data.setData(photoPath) ;
        setResult(RESULT_OK, data);
        finish() ;
    }
    public void retake(View v)
    {
        Button button = (Button)findViewById(R.id.button_accept);
        button.setVisibility(View.GONE);
        button = (Button)findViewById(R.id.button_capture) ;
        button.setVisibility(View.VISIBLE) ;
        button = (Button)findViewById(R.id.button_retake);
        button.setVisibility(View.GONE) ;

        mCamera.startPreview(); 
    }
    /**
     * A pretty basic example of an AsyncTask that takes the photo and
     * then sleeps for a defined period of time before finishing. Upon
     * finishing, it will restart the preview - Camera.startPreview().
     */

    private class TakePictureTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPostExecute(Void result) {
            // This returns the preview back to the live camera feed
            Button button = (Button)findViewById(R.id.button_accept) ;
            button.setVisibility(View.VISIBLE) ;
            button = (Button)findViewById(R.id.button_retake) ;
            button.setVisibility(View.VISIBLE);
            button = (Button)findViewById(R.id.button_capture);
            button.setVisibility(View.GONE);
            //mCamera.startPreview();
        }

        @Override
        protected Void doInBackground(Void... params) {
            mCamera.takePicture(null, null, mPicture);

            // Sleep for however long, you could store this in a variable and
            // have it updated by a menu item which the user selects.
            try {
                Thread.sleep(3000); // 3 second preview
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return null;
        }

    }

}

在我的应用程序的清单中,我已将此活动方向更改为肖像!

有什么问题?它为什么会这样?

1 个答案:

答案 0 :(得分:1)

在早期版本的Android中,这恰好是 bug 。 解决方法是默认旋转相机

if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        camera.setDisplayOrientation(90);
        lp.height = previewSurfaceHeight;
        lp.width = (int) (previewSurfaceHeight / aspect);
    } else {
        camera.setDisplayOrientation(0);
        lp.width = previewSurfaceWidth;
        lp.height = (int) (previewSurfaceWidth / aspect);
    }