13

For some reason, my camera app saves all photos rotated 90 degrees (pictures only look right when taken with camera on landscape mode) I believe onPictureTaken should rotate photos automatically but I read there is a problem with Samsung devices (I haven't been able to test it on another brand so I don't know if it's the case). This is my code:

   public void onPictureTaken(byte[] data, Camera camera) {
      // Generate file name
      FileOutputStream outStream = null;
      outStream = new FileOutputStream(filePath);
      outStream.write(data);
      outStream.close();

I was thinking it could be fixed by checking the orientation and rotating the byte array but there must be a more straightforward way to do it since handling byte arrays is a pain. How can I make sure photos are saved matching the orientation they were taken?

lisovaccaro
  • 32,502
  • 98
  • 258
  • 410
  • See a similar question [here](http://stackoverflow.com/questions/11674816/android-image-orientation-issue-with-custom-camera-activity). – DevinFalgoust Jan 28 '13 at 16:42
  • I had seen that answer. I just downloaded the source he provided and it's actually not for a camera app but for using the default camera to take a picture. I simply don't understand how to implement the code on the answer. There is a bitmap variable I don't have. If you know how to include the answer inside onPictureTaken I'll accept the answer. – lisovaccaro Jan 28 '13 at 18:01

3 Answers3

0

Try something like this:

int orientation = Exif.getOrientation(data);
Log.d("#", "onPictureTaken().orientation = " + orientation);
if(orientation != 0) {
     Bitmap bmpSrc = BitmapFactory.decodeByteArray(data, 0, data.length);
     Bitmap bmpRotated = CameraUtil.rotate(bmpSrc, orientation);
     bmpSrc.recycle();


       try {

             FileOutputStream localFileOutputStream = new FileOutputStream(filePath);
             bmpRotated.compress(Bitmap.CompressFormat.JPEG, 90,localFileOutputStream);
             localFileOutputStream.flush();
             localFileOutputStream.close();
             bmpRotated.recycle();

           }
        catch (FileNotFoundException e) 
           {
              e.printStackTrace();
           }
        catch (IOException e) 
           {
               e.printStackTrace();
           }

      } else {

          try {

               FileOutputStream localFileOutputStream = new FileOutputStream(filePath);
               localFileOutputStream.write(data);
               localFileOutputStream.flush();
               localFileOutputStream.close();

               } catch (IOException localIOException)
                  {
                                        Log.e("#",localIOException.getMessage());
                  }
   }
GioLaq
  • 2,489
  • 21
  • 26
0

There are different ways to get your image, as data, as stream, as file, also it is different for camera and gallery and other apps. For each of them you have another way to access the orientation tag. Once you have the orientation, you can rotate your image.

You - or for that matter everyone - should really get a Nexus, they are nice and rotate the image for you and set orientation to 0, while the lazy ones like Samsung just store the image and set the orientation tag. ;)

Kay
  • 71
  • 2
0

Assuming you're using the Android graphics framework, something like the following might work for you:

public void onPictureTaken(byte[] data, Camera camera) {
    try {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        ExifInterface exif = new ExifInterface(filePath);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.postRotate(90);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.postRotate(180);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.postRotate(270);
                break;
            default:
                break;
        }
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        FileOutputStream outStream = new FileOutputStream(filePath);
        rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  • First, we can use the Bitmap object as an easy way to decode and manipulate image data.
  • Then we create a Matrix because rotation is a linear transformation represented by matrix multiplication and because we don't need to manipulate pixel values ​​directly.
  • We then use the Exif metadata to determine how we need to rotate the image to get it oriented correctly.
  • After creating the correct rotation matrix for the image, create a new Bitmap using the new transformation Matrix and the original Bitmap.
  • Finally, we use FileOutputStream to write the image to the predefined class member filePath.
24tr6637
  • 16
  • 2