2015-01-14 2 views
2

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

Итак, прежде всего, я хотел бы знать ориентацию изображения и этот момент, который я застрял. Я всегда получаю ориентацию 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 

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

+0

Похоже, что на более мощном (последнем) оборудовании для Android ориентация EXIF ​​не указана, поскольку приложение камеры поворачивает пиксели перед кодированием JPEG. На более медленном оборудовании (в старые времена) изображение будет записано в ориентации по умолчанию, и фактическая ориентация будет сохранена в информации EXIF. – BitBank

+0

Так есть способ на самом деле сделать это? –

+1

Похоже, вы можете только сказать, было ли изображение сделано в портретном или ландшафтном формате по ширине и высоте. Истинная ориентация, похоже, не доступна. – BitBank

ответ

9

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

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

+1

Моя божественность Я искал ответ такого рода в течение 2 дней. Поскольку ваш ответ я нашел обновленный ответ, который действительно работает: http://stackoverflow.com/a/26141254/1332549 – MiguelHincapieC

+0

Лучшим подходом к работе с ориентационными фотографиями является [это] (http://stackoverflow.com/a/26141254/1332549). – MiguelHincapieC

+0

FYI - на Galaxy S6 Samsung записывает тег ориентации EXIF, поэтому он не повсеместно потерян. – BitBank

0

В этом коде

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 ​​из исходных байтов изображения.

+0

Можете ли вы помочь мне с фактическим кодом? Я этого не делал раньше. –

+0

ОК, я только что обновил свой ответ с линией, которую вы отсутствовали –

+0

К сожалению, все тот же результат. –

Смежные вопросы