2014-04-21 42 views
7

Napisałem działanie Androida, które przechwytuje zdjęcie programowo. Chcę zapisać obraz jako JPEG z odpowiednimi danymi orientacji EXIF ​​(tak jak aplikacja Android aparatu działa automatycznie).Ustawienie orientacji EXIF ​​dla zdjęć Androida

Oto metoda faktycznie zrobieniu zdjęcia (usunąłem bloków try/catch):

private void takePhoto() { 

    camera = Camera.open(); 
    SurfaceTexture dummySurfaceTexture = new SurfaceTexture(0); 
    camera.setPreviewTexture(dummySurfaceTexture); 
    camera.startPreview(); 
    camera.takePicture(null, null, jpgCallback); 
} 

... i zwrotna:

private Camera.PictureCallback jpgCallback = new Camera.PictureCallback() { 
    public void onPictureTaken(byte[] data, Camera camera) { 

     releaseCamera(); 
     savePhoto(data); 
}; 

Zdjęcie jest zrobione poprawnie, ale moim problemem jest to, że dane EXIF ​​pokazują, że orientacja jest ustawiona na "Orientacja obrazu: góra, lewa ręka", niezależnie od orientacji urządzenia, tak że po załadowaniu zdjęcia pojawia się do góry nogami lub obrócona.

Czy muszę ręcznie przechwytywać orientację urządzenia (rolka, skok, azymut) i samemu zapisać orientację EXIF? W jaki sposób aplikacja Aparat automatycznie zapisuje te dane poprawnie? Czy ktoś wie o sposobie poprawnego ustawienia tego atrybutu?

EDYCJA: Nie mogę użyć orientacji ekranu, ponieważ działanie jest zablokowane w trybie portretu.

+0

Przeczytałem już tę odpowiedź, ale nie można jej użyć, ponieważ moja aktywność jest zablokowana w trybie portretu. https://stackoverflow.com/questions/13245556/exif-orientation-tag-value-always-0-for-image-taking-w-portret-camera-app-and/13323987#13323987 –

Odpowiedz

-2
ExifInterface exif; 
     try { 
      exif = new ExifInterface(filePath); 

      int orientation = exif.getAttributeInt(
        ExifInterface.TAG_ORIENTATION, 0); 
      Log.d("EXIF", "Exif: " + orientation); 
      Matrix matrix = new Matrix(); 
      if (orientation == 6) { 
       matrix.postRotate(90); 
       Log.d("EXIF", "Exif: " + orientation); 
      } else if (orientation == 3) { 
       matrix.postRotate(180); 
       Log.d("EXIF", "Exif: " + orientation); 
      } else if (orientation == 8) { 
       matrix.postRotate(270); 
       Log.d("EXIF", "Exif: " + orientation); 
      } 
14

Nie musisz samodzielnie pisać orientacji EXIF, ale przed zrobieniem zdjęcia musisz poinformować podsystem kamery o orientacji urządzenia. Nie ma dostępu do tych informacji samodzielnie. Po ustawieniu podsystem kamery ustawi pole EXIF ​​lub obróci dane obrazu, aby zorientować obraz prawidłowo (co odbywa się w zależności od konkretnego urządzenia).

powiedzieć aparatem orientację chcesz do zdjęć swoimi wciąż używać Camera.Parameters.setRotation():

Jest kod referencyjny w docs programistycznych dla jak go używać prawidłowo, co jest nieco kłopotliwe, ponieważ wartość ustawić zależy na 1) orientację czujnika kamery i 2) orientację interfejsu użytkownika w stosunku do normalnej orientacji urządzenia. Mam skopiowane tutaj kod przykładowy, który wykorzystuje OrientationEventListener i zakłada masz Camera.Parameters obiektów nazywa mParameters:

public void onOrientationChanged(int orientation) { 
    if (orientation == ORIENTATION_UNKNOWN) return; 
    android.hardware.Camera.CameraInfo info = 
     new android.hardware.Camera.CameraInfo(); 
    android.hardware.Camera.getCameraInfo(cameraId, info); 
    orientation = (orientation + 45)/90 * 90; 
    int rotation = 0; 
    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { 
    rotation = (info.orientation - orientation + 360) % 360; 
    } else { // back-facing camera 
    rotation = (info.orientation + orientation) % 360; 
    } 
    mParameters.setRotation(rotation); 
} 

Następnie przed rozmowy takePicture, trzeba zadzwonić Camera.setParameters (mParameters).

W konkretnym przypadku możesz zapytać o orientację tuż przed zrobieniem zdjęcia i użyć logiki w przykładowym kodzie do obliczenia obrotu. Następnie pobierz parametry kamery za pomocą Camera.getParameters(), wywołaj funkcję setRotation, a następnie wywołaj Camera.setParameters().