6

setRotation method in Camera.Parameters does not work in all devices. Somebody suggests to manually change the EXIF information to solve the problem. Can you give me a short example on how to set the exif information with ExifInterface in such a way to set the image orientation as portrait?

private int savePicture(byte[] data)
{
       File pictureFile = getOutputMediaFile();
       if (pictureFile == null)
           return FILE_CREATION_ERROR;

       try {
           FileOutputStream fos = new FileOutputStream(pictureFile);
           fos.write(data);
           fos.close();
       } catch (FileNotFoundException e) {
           return FILE_NOT_FOUND;
       } catch (IOException e) {
           return ACCESSING_FILE_ERROR;
       }

   return OKAY;
}

I've tried with this:

    try {
        ExifInterface exifi = new ExifInterface(pictureFile.getAbsolutePath());
        exifi.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90));
        exifi.saveAttributes();
    } catch (IOException e) {
        Log.e(TAG, "Exif error");
    }

but nothing change when I visualize the pictures from the android gallery.

user2923045
  • 369
  • 2
  • 6
  • 16

4 Answers4

10

For those who actually want to write these EXIF information out, here is some code:

ExifInterface exifInterface = new ExifInterface(someFile.getPath());
exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION,
                           String.valueOf(orientation));
exifInterface.saveAttributes();

whereas orientation is one of the standard orientations, i.e. ExifInterface.ORIENTATION_ROTATE_{90,180,270}.

Thomas Keller
  • 5,933
  • 6
  • 48
  • 80
3

If orientation is saved into file but doesn't appear in the gallery it may be because of orientation is cached in MediaStore. So you need to try to update this information there also.

Here is the code snipped (untested)

/**
 * @param fileUri the media store file uri
 * @param orientation in degrees 0, 90, 180, 270
 * @param context
 * @return
 */
public boolean setOrientation(Uri fileUri, int orientation, Context context) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.ORIENTATION, orientation);
    int rowsUpdated = context.getContentResolver().update(fileUri, values, null, null);
    return rowsUpdated > 0;
}

/**
 * Get content uri for the file path
 * 
 * @param path
 * @param context
 * @return
 */
public Uri getContentUriForFilePath(String path, Context context) {
    String[] projection = {
        MediaStore.Images.Media._ID
    };
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
            MediaStore.Images.Media.DATA + " = ?", new String[] {
                path
            }, null);
    Uri result = null;
    if (cursor != null) {
        try {
            if (cursor.moveToNext()) {
                long mediaId = cursor.getLong(0);
                result = ContentUris.withAppendedId(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mediaId);
            }
        } finally {
            cursor.close();
        }
    }
    return result;
}
Eugene Popovich
  • 3,343
  • 2
  • 30
  • 33
1

Well, I was stuck in such kind of problem, and tried the solution that you are working on and ended up using Matrix function.

Whatever the images I was taking, it was all landscape, so in app I just applied the below code, and it worked well:-

Matrix matrix = new Matrix();
//set image rotation value to 90 degrees in matrix.
matrix.postRotate(90);
//supply the original width and height, if you don't want to change the height and width of //bitmap.
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0, newWidth, newHeight, matrix, true);
Bette Devine
  • 1,196
  • 1
  • 9
  • 23
  • Ok, but if we do in this way there will be a lot of performance degradation as: 1) write byte[] data into a file 2) read the file and extract exif info 3) decompress the file to a bmp 4) rotate the image 5) compress again in jpeg 6) overwrite the file. I was wondering whether there is a more simple solution that works directly on data[] – user2923045 Nov 03 '13 at 16:58
  • 1
    The way you are handling the problem, it will deteriorate the performance of app, use it wisely, there is no need to handle the images like the way you are explaining, save the image as it is no need to apply all the inputs you explained, when you need to show it in view, do it at run time and deal with viewing images wisely, it will not deteriorate its performance. – Bette Devine Nov 04 '13 at 01:31
  • I disagree with you Bette. I want to use the android gallery for showing the images and the android gallery shows them with a wrong orientation. – user2923045 Nov 04 '13 at 19:27
  • On what point you disagree? Why do you want to make your images visible in gallery? See the links, if they are useful to you. https://android.googlesource.com/platform/frameworks/base/+/master/media/java/android/media/ExifInterface.java http://stackoverflow.com/questions/5186795/exifinterface-doesnt-update-exif-tags – Bette Devine Nov 05 '13 at 04:54
  • 1
    No, I mean that I do not want to develop my own gallery. For browsing the picture I take using the camera app I am developing I want to use the gallery app already installed in any device. But, the pictures taken when the phone is in portrait using the example code in the android.development and in several tutorials on-line, are unusable because they are visualized in the wrong orientation. – user2923045 Nov 06 '13 at 06:06
  • you could also use the same matrix and set it on the image view directly; just be sure to set the iv's scale type to matrix, and probably have to call invalidate on it – wkhatch Jan 22 '15 at 02:57
1

its below code is work for me ..

File imageFile = new File(string_path); //add path here

        ExifInterface exif = null;

        try {

            exif = new ExifInterface(imageFile.getAbsolutePath());

        } catch (IOException e) {

            e.printStackTrace();

        }

        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        int rotate = 0;

        switch (orientation) {

            case ORIENTATION_ROTATE_270:
                rotate = 270;
                break;

            case ORIENTATION_ROTATE_180:
                rotate = 180;
                break;

            case ORIENTATION_ROTATE_90:
                rotate = 90;
                break;

        }

        Matrix matrix = new Matrix();

        matrix.postRotate(rotate);

        this.btmap = Bitmap.createBitmap(this.btmap, 0, 0, this.btmap.getWidth(), this.btmap.getHeight(), matrix, true);

        Glide.with(this).load(this.btmap).into((ImageView) getActivity().findViewById(R.id.btnimg));