2011-12-01 102 views
22

我在寫一個使用相機的Android應用程序。 我的相機顯示方向設置爲90,我的活動是在人像方向:拍攝後應該旋轉Android攝像頭生成的圖像嗎?

camera.setDisplayOrientation(90); 

我得到一個很好的面向預覽圖片,但由此產生的圖像旋轉到-90度(逆時針)和

exif.getAttribute(ExifInterface.TAG_ORIENTATION) 

回報ORIENTATION_NORMAL
它是預期的行爲?捕獲後我應該旋轉結果圖像嗎?

設備 - 的Nexus S,API - 10

+0

同樣的事情正在發生在我身上;我也在Nexus S API 10上;感謝您的問題。 – serkanozel

+0

在這裏回答http://stackoverflow.com/questions/14066038/why-image-captured-using-camera-intent-gets-rotated-on-some-devices-in-android –

+1

可能的重複[爲什麼捕獲的圖像使用相機意圖在Android上的某些設備上旋轉?](https://stackoverflow.com/questions/14066038/why-does-an-image-captured-using-camera-intent-gets-rotated-on-some-devices -on-a) – bummi

回答

13

問題是相機的方向是一個完整的災難(如拍攝圖像),因爲原始設備製造商不符合標準。 HTC手機做事情的方式之一,三星手機做不同的方式,Nexus線似乎堅持不管哪個廠商,基於CM7的ROM我認爲遵循標準無論哪個硬件,但你明白了。你必須根據電話/ ROM確定要做什麼。看到這裏討論:Android camera unexplainable rotation on capture for some devices (not in EXIF)

21

試試這個

try { 
     File f = new File(imagePath); 
     ExifInterface exif = new ExifInterface(f.getPath()); 
     int orientation = exif.getAttributeInt(
       ExifInterface.TAG_ORIENTATION, 
       ExifInterface.ORIENTATION_NORMAL); 

     int angle = 0; 

     if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { 
      angle = 90; 
     } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { 
      angle = 180; 
     } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { 
      angle = 270; 
     } 

     Matrix mat = new Matrix(); 
     mat.postRotate(angle); 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inSampleSize = 2; 

     Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), 
       null, options); 
     bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), 
       bmp.getHeight(), mat, true); 
     ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream(); 
     bitmap.compress(Bitmap.CompressFormat.PNG, 100, 
       outstudentstreamOutputStream); 
     imageView.setImageBitmap(bitmap); 

    } catch (IOException e) { 
     Log.w("TAG", "-- Error in setting image"); 
    } catch (OutOfMemoryError oom) { 
     Log.w("TAG", "-- OOM Error in setting image"); 
    } 

它將工作

+2

對此工作的任何確認? – JoaoFilipeClementeMartins

+2

不,我的工作! – AabidMulani

+2

好奇你是如何得出結論的,這將適用於所有設備。 – sudocoder

1
camera.setDisplayOrientation(90); 

我已經編碼只肖像模式的應用程序。

將相機旋轉到90度,這可能會導致不適合在Android的 所有設備爲了讓所有的Android設備使用下面的代碼,在開發者網站吹罰正確的預覽。

下面,你必須把你的活動,cameraId =後面是0和前置攝像頭爲1

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { 
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); 
    android.hardware.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; 
    //int currentapiVersion = android.os.Build.VERSION.SDK_INT; 
     // do something for phones running an SDK before lollipop 
     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); 
} 

這是如何設置setDisplayOrientation相機

現在,你可能會遇到麻煩是節約在正確的方向捕獲的圖像,這是相機API中的錯誤,以支持所有Android設備。 可以克服使用下面

PLS注意EXIF值步驟不會給你正確的值中的所有設備,因此,這會幫助你

int CameraEyeValue = setPhotoOrientation(CameraActivity.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back 

通過使用我們之前所使用的相同的概念DisplayOrientation

public int setPhotoOrientation(Activity activity, int cameraId) { 
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); 
    android.hardware.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; 
    // do something for phones running an SDK before lollipop 
    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; 
    } 

    return result; 
} 

因此,最終的PictureCallBack方法應該看起來像

private PictureCallback getPictureCallback() { 
    PictureCallback picture = new PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 
      //make a new picture file 
      File pictureFile = getOutputMediaFile(); 

      if (pictureFile == null) { 
       return; 
      } 
      try { 
       //write the file 
       FileOutputStream fos = new FileOutputStream(pictureFile); 
       Bitmap bm=null; 

       // COnverting ByteArray to Bitmap - >Rotate and Convert back to Data 
       if (data != null) { 
        int screenWidth = getResources().getDisplayMetrics().widthPixels; 
        int screenHeight = getResources().getDisplayMetrics().heightPixels; 
        bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0); 

        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
         // Notice that width and height are reversed 
         Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); 
         int w = scaled.getWidth(); 
         int h = scaled.getHeight(); 
         // Setting post rotate to 90 
         Matrix mtx = new Matrix(); 

         int CameraEyeValue = setPhotoOrientation(AndroidCameraExample.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back 
         if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation 
          if (CameraEyeValue == 270) { 
           mtx.postRotate(90); 
          } else if (CameraEyeValue == 90) { 
           mtx.postRotate(270); 
          } 
         }else{ 
           mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation 
         } 

         bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true); 
        }else{// LANDSCAPE MODE 
         //No need to reverse width and height 
         Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth, screenHeight, true); 
         bm=scaled; 
        } 
       } 
       // COnverting the Die photo to Bitmap 



       ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
       bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
       byte[] byteArray = stream.toByteArray(); 
       fos.write(byteArray); 
       //fos.write(data); 
       fos.close(); 

       Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG); 
       toast.show(); 

      } catch (FileNotFoundException e) { 
      } catch (IOException e) { 
      } 

      //refresh camera to continue preview 
      mPreview.refreshCamera(mCamera); 
      mPreview.setCameraDisplayOrientation(CameraActivity.this,GlobalCameraId,mCamera); 
     } 
    }; 
    return picture; 
} 

由於僅適用於使用前置和後置攝像頭的肖像模式,因此在所有Android設備上都使用正確的肖像方向將圖片旋轉爲僅肖像模式。

景觀可以讓這個爲參考,並在下面的塊

if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation 
     if (CameraEyeValue == 270) { 
      mtx.postRotate(90); //change Here 
      } else if (CameraEyeValue == 90) { 
      mtx.postRotate(270);//change Here 
      } 
     }else{ 
      mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation //change Here 
     } 
+0

我想捕捉圖像總是肖像,但我找不到位圖的旋轉角度。 –

4

我有同樣的問題,像你這樣的變化,但我已經修復它。
你應該使用相同的代碼:

Camera.Parameters parameters = camera.getParameters(); 
parameters.setRotation(90); 
camera.setParameters(parameters); 

我希望你可以使用此代碼太。