2014-01-09 47 views
2

我正在嘗試爲Android應用程序創建自定義相機。我已經成功地用我自己的客戶界面獲取相機拍照並保存。 SurfaceView預覽也以縱向模式顯示(這也是期望的)。我的問題是,在保存照片後,它們不會以照相機拍攝照片時的方向顯示。我知道在這裏有幾個和我的非常相似的問題,但他們一直無法幫助我。我用於測試的手機(當然不包括仿真器)是HTC Evo 4G。以下是我的代碼分解。非常感謝您提供的任何幫助!請注意,我在一個類中完成了所有這些工作,並將圖像保存爲文件而不是位圖。Android定製相機圖像保存方向錯誤

清單

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

<activity android:name=".CameraClass" 
      android:screenOrientation="portrait" /> 

按鈕單擊

btn_takepicture.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        // TODO Auto-generated method stub 
        mCamera.takePicture(null, null, pic_call); 

        Toast.makeText(getApplicationContext(), "Picture Added!", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

圖片回調方法

private PictureCallback pic_call= new PictureCallback() { 
     public void onPictureTaken(byte[] datas, Camera mCamera) { 
      // TODO Auto-generated method stub 
      String root = Environment.getExternalStorageDirectory().toString(); 
      File myDir = new File(root + "/Images/"); 
      myDir.mkdirs(); 
      if (myDir.exists()){ 

     } 

     Random generator = new Random(); 
     int n = 10000; 
     n = generator.nextInt(n); 
     String fname = "Image"+ n +".jpg"; 
     File file = new File (myDir, fname); 
     Uri uriSavedImage = Uri.fromFile(file); 


     sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
       Uri.parse("file://"+ Environment.getExternalStorageDirectory()))); 
     Intent is = new Intent(CameraClass.this, Display.class); 
     is.putExtras(basket); 

     try { 
      file.createNewFile(); 
      FileOutputStream fos = new FileOutputStream(file); 
      fos.write(datas); 
      fos.close(); 
     } catch (FileNotFoundException e) { 

     } catch (IOException e) {     
     } 
     startActivity(is); 
    } 

}; 

攝像機暫停/釋方法

@Override 
    protected void onPause() { 
     super.onPause(); 
     releaseCamera(); 
    } 

    private void releaseCamera() { 
     // TODO Auto-generated method stub 
     if (mCamera != null){ 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

表面改變方法

@Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     // TODO Auto-generated method stub 
     if (surfaceHolder.getSurface() == null) { 

     } 
     try { 
      mCamera.stopPreview(); 
     } 
     catch (Exception e) { 

     } 
     try { 
      mCamera.setPreviewDisplay(surfaceHolder); 
      mCamera.startPreview(); 
     } 
     catch (Exception e) { 
      Log.d("TAG", "Error starting mCamera preview: " + e.getMessage()); 
     } 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.set("orientation", "portrait"); 

     if(mCamera != null) { 
      try { 
       mCamera.setPreviewDisplay(surfaceHolder); 
       mCamera.startPreview(); 
       previewing = true; 
      } 
      catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

表面上產生

public void surfaceCreated(SurfaceHolder holder) { 
     try { 
      mCamera = Camera.open(); 
      camParam = mCamera.getParameters(); 
      Camera.Parameters params = mCamera.getParameters(); 
      String currentversion = android.os.Build.VERSION.SDK; 
      Log.d("System out", "currentVersion " + currentversion); 
      int currentInt = android.os.Build.VERSION.SDK_INT; 
      Log.d("System out", "currentVersion " + currentInt); 

      if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
       if (currentInt != 7) { 
        mCamera.setDisplayOrientation(90); 
       } else { 
        Log.d("System out", "Portrait " + currentInt); 

        params.setRotation(90); 

        mCamera.setParameters(params); 
       } 
      } 
      if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
       if (currentInt != 7) { 
        mCamera.setDisplayOrientation(0); 
       } else { 
        Log.d("System out", "Landscape " + currentInt); 
        params.set("orientation", "landscape"); 
        params.set("rotation", 90); 
        mCamera.setParameters(params); 
       } 
      } 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      Log.d("CAMERA", e.getMessage()); 
     } 
    } 

面銷燬方法

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

    } 

設置攝像頭定位方法

public static void setCameraDisplayOrientation(Activity activity, int cameraID, android.hardware.Camera mCamera) { 
     Camera.CameraInfo info = new Camera.CameraInfo(); 
     Camera.getCameraInfo(cameraID, info); 
     int rotation = activity.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; 
     } 
     else { 
      result = (info.orientation - degrees + 360) % 360; 
     } 
     mCamera.setDisplayOrientation(result); 
    } 

回答

4

在保存時有些設備不旋轉圖像,而是設置一個EXIF頭說:「哎,圖片瀏覽器!你能像顯示它時旋轉這個圖像嗎? kthxbye」。

這就是爲什麼在my CWAC-Camera library,我經過了迴旋旋轉這些圖像,因爲不是所有的圖像瀏覽器將履行這些EXIF頭。

+0

謝謝你的解釋,你做的方式,它幫助清理我對於發生什麼事情感到困惑!我會看看圖書館,看看是否有方法將它與我的項目集成。 – BossWalrus

+0

@CommonsWare你真棒! –