2011-12-01 42 views
22

Tôi đang viết một ứng dụng Android sử dụng máy ảnh. Tôi đang thiết định hướng hiển thị camera đến 90, hoạt động của tôi là trong một hướng dọc:Hình ảnh kết quả của máy ảnh Android phải được xoay sau khi chụp?

camera.setDisplayOrientation(90); 

Tôi nhận được một bức tranh xem trước cũng định hướng, nhưng hình ảnh thu được quay đến -90 độ (truy cập chiều kim đồng hồ) và

exif.getAttribute(ExifInterface.TAG_ORIENTATION) 

lợi nhuận ORIENTATION_NORMAL
có dự kiến ​​hành vi? Tôi có nên xoay hình ảnh kết quả sau khi chụp không?

Device - Nexus S, API - 10

+0

Điều tương tự đang xảy ra với tôi; Tôi cũng có trên Nexus S API 10; cảm ơn câu hỏi. – serkanozel

+0

Trả lời tại đây http://stackoverflow.com/questions/14066038/why-image-captured-using-camera-intent-gets-rotated-on-some-devices-in-android –

+1

Sao chép có thể có của [Tại sao ảnh được chụp sử dụng mục đích máy ảnh được xoay trên một số thiết bị trên Android?] (https://stackoverflow.com/questions/14066038/why-does-an-image-captured-using-camera-intent-gets-rotated-on-some-devices -on-a) – bummi

Trả lời

13

Vấn đề là định hướng máy ảnh là một thảm họa đầy đủ (như được chụp ảnh) vì các OEM không tuân thủ tiêu chuẩn. HTC điện thoại làm điều một cách, điện thoại Samsung làm điều đó một cách khác nhau, dòng Nexus dường như tuân thủ không có vấn đề mà nhà cung cấp, CM7 ROM dựa tôi nghĩ theo tiêu chuẩn không có vấn đề mà phần cứng, nhưng bạn có được ý tưởng. Bạn phải xác định phải làm gì dựa trên điện thoại/ROM. Xem thảo luận ở đây: Android camera unexplainable rotation on capture for some devices (not in EXIF)

21

Hãy thử điều này

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"); 
    } 

Nó sẽ làm việc

+2

Bất kỳ xác nhận nào về hoạt động này? – JoaoFilipeClementeMartins

+2

Không, công việc dint dành cho tôi! – AabidMulani

+2

tò mò làm thế nào bạn đến kết luận rằng điều này sẽ làm việc cho tất cả các thiết bị. – sudocoder

1
camera.setDisplayOrientation(90); 

Tôi đã được mã hóa ứng dụng cho chỉ Portrait Mode.

Sẽ làm cho máy ảnh quay ở 90 độ và điều này có thể không phù hợp với tất cả các thiết bị trong android Để có được Xem trước chính xác cho tất cả các thiết bị Android sử dụng mã sau được quy định trong trang web của nhà phát triển.

Dưới đây bạn phải gửi hoạt động của bạn, cameraId = lại là 0 và cho Máy ảnh trước là 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); 
} 

Đây là cách để thiết lập setDisplayOrientation cho camera

Bây giờ bạn có thể gặp khó khăn khi đang cứu hình ảnh được chụp ở định hướng đúng, đó là lỗi trong API camera để hỗ trợ tất cả các thiết bị trong Android. bạn có thể khắc phục bằng cách sử dụng bước dưới đây

PLS LƯU Ý EXIF ​​GIÁ TRỊ SẼ KHÔNG CHO BẠN GIÁ TRỊ ĐÚNG TRONG TẤT CẢ CÁC THIẾT BỊ, Vì vậy, điều này sẽ giúp bạn

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

Bằng việc sử dụng khái niệm tương tự, chúng tôi sử dụng trước khi cho 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; 
} 

Vì vậy, phương pháp PictureCallBack cuối cùng của bạn sẽ trông như thế

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; 
} 

Vì chỉ hoạt động cho chế độ Chân dung bằng camera Trước và sau Ảnh được xoay sang chế độ chân dung chỉ với Hướng dọc chính xác trong tất cả các thiết bị Android.

Đối với phong cảnh bạn có thể làm điều này như tài liệu tham khảo và thực hiện thay đổi trong khối dưới

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

tôi muốn chụp ảnh luôn ở chế độ dọc nhưng tôi không thể tìm thấy góc quay cho bitmap. –

4

tôi đã cùng một vấn đề như bạn, nhưng tôi đã sửa chữa nó.
Bạn nên sử dụng cùng mã:

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

Tôi hy vọng bạn có thể sử dụng mã này quá.

Các vấn đề liên quan