2014-04-21 12 views
7

Ho scritto un'attività Android che acquisisce una foto programmaticamente. Voglio salvare l'immagine come JPEG con i dati di orientamento EXIF ​​corretti (proprio come fa l'app nativa per Android Camera).Impostazione di Android Photo Orientamento EXIF ​​

Ecco il metodo per prendere effettivamente la foto (ho rimosso i blocchi try/catch):

private void takePhoto() { 

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

... e il callback:

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

     releaseCamera(); 
     savePhoto(data); 
}; 

La foto è presa correttamente, ma il mio problema è che i dati EXIF ​​mostrano che l'orientamento è impostato su "Image Orientation: Top, Left-Hand" indipendentemente dall'orientamento del dispositivo, in modo tale che quando carico la foto appare capovolta o ruotato.

Ho davvero bisogno di acquisire manualmente l'orientamento del dispositivo (roll, pitch, azimuth) e scrivere da solo l'orientamento EXIF? In che modo l'app Camera scrive automaticamente questi dati correttamente? Qualcuno sa di un modo per impostare correttamente questo attributo?

MODIFICA: non è possibile utilizzare l'orientamento dello schermo poiché l'attività è bloccata in modalità verticale.

+0

Ho già letto questa risposta, ma non può essere utilizzata poiché la mia attività è bloccata in modalità verticale. https://stackoverflow.com/questions/13245556/exif-orientation-tag-value-always-0-for-image-taken-with-portrait-camera-app-and/13323987#13323987 –

risposta

-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

Non è necessario scrivere l'orientamento EXIF ​​da soli, ma è necessario indicare al sottosistema della fotocamera l'orientamento del dispositivo prima di scattare una foto. Non ha accesso a tali informazioni da solo. Una volta impostato, il sottosistema della fotocamera imposterà il campo EXIF ​​o ruoterà i dati dell'immagine per orientare correttamente l'immagine (operazione che dipende dal dispositivo specifico).

A dire la telecamera l'orientamento desiderato per le immagini fisse, utilizzare Camera.Parameters.setRotation():

C'è codice di riferimento nella documentazione di sviluppo per come usarlo correttamente, che è un po 'complicato, perché il valore impostato dipende su 1) l'orientamento del sensore della fotocamera e 2) l'orientamento dell'interfaccia utente, in relazione all'orientamento normale del dispositivo. Ho copiato il codice di esempio qui, che utilizza un OrientationEventListener e presuppone una Camera.Parameters oggetto chiamato 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); 
} 

Poi, prima della chiamata takePicture, è necessario chiamare Camera.setParameters (mParameters).

Nel caso specifico, è possibile interrogare l'orientamento prima di scattare la foto e utilizzare la logica nel codice di esempio per calcolare la rotazione. E quindi ottenere i parametri della telecamera con Camera.getParameters(), chiamare setRotation e quindi chiamare Camera.setParameters().

Problemi correlati