2013-03-03 130 views
0

我已經寫了一個相機應用程序,但是當我想要顯示相機的實時預覽(拍攝照片之前)時,預覽旋轉了90度!這裏是我的相機活動代碼:爲什麼相機的實時預覽旋轉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

這恰好是早期版本的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); 
    } 
+0

謝謝,代碼的作品,但如果Android版本更新,沒有錯誤,它也在那裏工作? – Navid777 2013-03-03 14:47:01

+0

@ Navid777爲了最終確定你應該喚醒Android模擬器。 – poitroae 2013-03-03 14:48:20