2016-03-30 4 views
0

Ich habe eine benutzerdefinierte Kamera-Implementierung in meinem Projekt. Es funktioniert gut, wenn ich die hintere Kamera des Geräts benutze. Bei der Aufnahme von Bildern mit der Frontkamera im Hoch- oder Querformat wird das Bild umgedreht. Im Querformat funktionieren beide Kameras einwandfrei.Das mit der vorderen Kamera aufgenommene Bild wird auf den Kopf gestellt

Ich habe SensorEventListener und Berechnen den orientation Wert in SensorChanged Rückruf implementiert, um ExifInterface.TAG_ORIENTATION in der aufgenommenen Datei zu setzen.

public void onSensorChanged(SensorEvent event) { 
     synchronized (this) { 
      if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 


       if (event.values[0] < 4 && event.values[0] > -4) { 
        if (event.values[1] > 0 && orientation != ExifInterface.ORIENTATION_ROTATE_90) { 
         // UP 
         orientation = ExifInterface.ORIENTATION_ROTATE_90; 
        } else if (event.values[1] < 0 && orientation != ExifInterface.ORIENTATION_ROTATE_270) { 
         // UP SIDE DOWN 
         orientation = ExifInterface.ORIENTATION_ROTATE_270; 
        } 
       } else if (event.values[1] < 4 && event.values[1] > -4) { 
        if (event.values[0] > 0 && orientation != ExifInterface.ORIENTATION_NORMAL) { 
         // LEFT 
         orientation = ExifInterface.ORIENTATION_NORMAL; 
        } else if (event.values[0] < 0 && orientation != ExifInterface.ORIENTATION_ROTATE_180) { 
         // RIGHT 
         orientation = ExifInterface.ORIENTATION_ROTATE_180; 
        } 
       } 

      } 

     } 
    } 

Der Grund, warum ich SensorEventListener bin mit, weil ich Rotation Animation, die auf dem Bildschirm, um die Symbole am Hinzufügen, wenn der Benutzer den Bildschirm dreht. Hier ist meine PictureCallback:

private Camera.PictureCallback mPictureCallBack = new Camera.PictureCallback() { 

     public void onPictureTaken(byte[] data, Camera camera) { 
      mCamera.stopPreview(); 

      File pictureFile = new File(fileName); 

      try { 
       FileOutputStream purge = new FileOutputStream(pictureFile); 
       purge.write(data); 
       purge.close(); 
      } catch (FileNotFoundException e) { 

      } catch (IOException e) { 

      } 

      // Adding Exif data for the orientation. 
      try { 

       exif = new ExifInterface(fileName); 
       exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation); 
       exif.saveAttributes(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    }; 

Zum Debuggen, wenn ich exif.setAttribute() den orientation Wert ExifInterface.ORIENTATION_ROTATE_90, falls es ist ExifInterface.ORIENTATION_ROTATE_270 und umgekehrt, es funktioniert gut. Meine Frage ist, was ist die beste und sicherste Sache, um dies zu beheben, so dass es am besten zu allen Geräten passt.

Note : Ich benutze keine Bitmaps in diesem ganzen Prozess. Ich schreibe die data in eine Datei und sende sie an eine andere Aktivität zurück, um das aufgenommene Bild anzuzeigen.

Jede Hilfe wird sehr geschätzt.

Antwort

0

Ich hatte dieses Problem vor einiger Zeit. Was ich getan habe, war, das Bild zu drehen und auf die negative Drehung des Geräts zu achten, wenn Sie eine Frontlinsenkamera verwenden. So Ihre Rotation konvertieren Sie etwas tun müssen:

//check first in which camera we are 
public boolean isFrontCamera(int cameraIndex) { 
    try { 
     if (mDeviceManager != null) { 
      CameraCharacteristics characteristics = mDeviceManager.getCameraManager().getCameraCharacteristics(String.valueOf(cameraIndex)); 

      return characteristics.get(CameraCharacteristics.LENS_FACING) 
        == CameraCharacteristics.LENS_FACING_FRONT; 
     } 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } catch (NullPointerException e) { 
     e.printStackTrace(); 
    } 

    return false; 
} 

    boolean mirror = isFrontCamera(Integer.parseInt(mCameraId)); 
       if (mirror) { 
        //Mirror image rotation is equal to the negative rotation of the device, but some external apps are not able to read negative numbers 
        //in image details, we do this to prevent the crash of this apps 
        rotation = 360 - rotation; 
        if (rotation == 360) { 
         rotation = 0; 
        } 
       } 

Später Sie Ihr Bild drehen müssen, bevor fügen Sie es Ihrer Ansicht können Sie eine Matrix wie folgt verwenden:

public static Bitmap rotateImage(Bitmap imageToOrient, int degreesToRotate) { 
    Bitmap result = imageToOrient; 
    try { 
     if (degreesToRotate != 0) { 
      Matrix matrix = new Matrix(); 
      matrix.setRotate(degreesToRotate); 
      result = Bitmap.createBitmap(
        imageToOrient, 
        0, 
        0, 
        imageToOrient.getWidth(), 
        imageToOrient.getHeight(), 
        matrix, 
        true); 
     } 
    } catch (Exception e) { 
     if (Log.isLoggable(TAG, Log.ERROR)) { 
      Log.e(TAG, "Exception when trying to orient image", e); 
     } 
    } 
    return result; 
} 

Ich weiß, dass Sie verwenden keine Bitmap, aber Sie können die Methode ändern, um ihr ein byteArray oder was auch immer Sie benötigen, zu senden.

Hoffe, dass es dir ein bisschen hilft! Mit freundlichen Grüßen!