С помощью API Android Camera привязанная ориентация фотографий всегда Undefined

Я использую камеру api, и сделанное фото всегда поворачивается на 90 градусов, и я хотел бы повернуть его.

Итак, прежде всего, я хотел бы знать ориентацию изображения, и этот момент я застрял. Я всегда получаю UNDEFDDED ориентацию в обоих направлениях.

Вот код:

    @Override
        public void onPictureTaken(byte[] data, Camera camera) {


            //Bitmap Options for lowering quality the bitmap to save memory
            Options options = new BitmapFactory.Options();
            options.inSampleSize = 4;
            options.inPreferredConfig = Bitmap.Config.RGB_565;

            //Make the bitmap
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);

            //Making the path, the root will be fine for tests
            String path = Environment.getExternalStorageDirectory().toString();

            //output stream
            OutputStream outputStream = null;
            //Making the file as a jpg
            File file = new File(path, "tmp_pic" + ".jpg"); // the File to save to
            try {

                //Writing the file
                outputStream = new FileOutputStream(file);
                outputStream.flush();
                outputStream.close(); // do not forget to close the stream


                //Getting the orientation in both possible ways
                int ori = getOrientationFromExif(file.getPath());
                int ori2 = getOrientationFromUri(Uri.fromFile(file));
            }
            catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            if (bitmap == null) {
                Toast.makeText(getApplicationContext(), "Error: Cant make photo.", Toast.LENGTH_SHORT).show();
            }
            else {
                PhotoTapView.photoViews.get(index).setPhotoImage(bitmap);
                finish();
            }
            cameraObject.release();
        }

Функции для ориентации:

    //Getting orientation from file URI
    private int getOrientationFromUri(Uri imageUri) {
    String[] orientationColumn = { MediaStore.Images.Media.ORIENTATION };
    Cursor cur = getContentResolver().query(imageUri, orientationColumn, null, null, null);
    int orientation = -1;
    if (cur != null && cur.moveToFirst()) {
        orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
    }
    Log.i("Orientation from Uri", orientation + "");
    return orientation;
}

    //Getting orientation from ExifInterface  
    private static int getOrientationFromExif(String imagePath) {
    int orientation = -1;
    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        Log.i("Orientation from Exif: ", exifOrientation + "");
        switch (exifOrientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                orientation = 270;
                Log.i("Orientation from Exif", "270");
            break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                orientation = 180;
                Log.i("Orientation from Exif", "180");
            break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                Log.i("Orientation from Exif", "90");
                orientation = 90;
            break;
            case ExifInterface.ORIENTATION_NORMAL:
                orientation = 0;
                Log.i("Orientation from Exif", "0 - Normal");
            break;
            case ExifInterface.ORIENTATION_UNDEFINED:
                orientation = -1;
                Log.e("Orientation from Exif", "UNDEFINED");
        }
    }
    catch (IOException e) {}
    return orientation;
}

Выход журнала:

01-14 19:46:09.468: E/Orientation from Exif(12411): UNDEFINED
01-14 19:46:09.468: I/Orientation from Uri(12411): -1

В чем может быть проблема?

Ответ 1

Я делал декодирование/наблюдение за изображениями Android JPEG с начала 2011 года, потому что я опубликовал приложение для просмотра изображений. В ранние дни изображения были закодированы в исходной ориентации датчика, и фактическая ориентация устройства была записана в метаданные EXIF. Начиная примерно 2 года назад, я заметил, что ориентация больше не записывалась в данные EXIF, и вместо этого приложение камеры вращало пиксели изображения до кодирования файлов JPEG. Я предполагаю, что это произошло из-за того, что некоторые зрители (* cough * Windows * cough *) игнорируют ориентацию EXIF ​​при отображении файлов JPEG и вместо того, чтобы ждать, пока Microsoft исправит это и обвинит Android в том, что он делает что-то неправильно, они решили использовать более быстрый процессор/память и просто повернуть изображение.

В результате, не зная ориентации EXIF, можно только определить, что фотография была захвачена в альбомной или портретной ориентации. Этот бит информации является лишь предположением, потому что большинство датчиков камеры шире, чем они высоки.

Ответ 2

В этом коде

outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);  // Add this line
outputStream.flush();
outputStream.close(); // do not forget to close the stream

Вы забыли написать байты в выходной поток. Таким образом, файл имеет длину 0 и, естественно, не содержит информации EXIF.

Также будьте осторожны, когда вы вызываете decodeByteArray, а затем сохраняете его снова, это также потеряет информацию EXIF! Вам нужно проанализировать EXIF ​​из исходных байтов изображения.