Intereting Posts
Интеграция с Android и Paypal API Получить GPS-местоположение в широковещательном приемнике / или услуге для передачи данных приемника Broadcast Каков наилучший серверный протокол связи с клиентами для использования в Android и iOS? Как удалить определенный фрагмент из предыдущего стека в android Как я могу получить правильный URL-адрес видеофайлу из встроенного видео? Как скрыть всплывающее окно Изменение ориентации с помощью ViewPager + FragmentPagerAdapter Как настроить панель выполнения на Android Добавить новые элементы в начало списка на Android? Является ли законным вызывать метод запуска дважды в одной теме? Заставить пользователей иметь последнюю версию приложения для Android Android string.xml чтение html тегов проблема Отправить личное сообщение моим друзьям с помощью myroid-приложения Android Calendar Provider: существует ли уникальный идентификатор событий, который можно использовать на нескольких устройствах? FFMPEG для инструментальных цепей Android: arm-linux-armeabi-eabi-pkg-config – существует ли какая-либо инструментальная цепочка, содержащая инструмент pkg-config

Данные Android EXIF ​​всегда 0, как его изменить?

У меня есть приложение, которое захватывает фотографии с помощью встроенной Camera а затем загружает их на сервер. Моя проблема в том, что все фотографии имеют значение ориентации EXIF ​​0, и это помешает отображению в другом месте.

Как изменить ориентацию EXIF? Я не ищу способ исправить это для каждого обстоятельства, просто измените его на другое значение.

Я использую Samsung Galaxy Note 4

Я попробовал это решение, которое устанавливает ориентацию камеры перед съемкой: настройка Android Photo EXIF ​​Orientation

 Camera c = Camera.open(); c.setDisplayOrientation(90); Camera.Parameters params = mCamera.getParameters(); params.setRotation(0); // tried 0, 90, 180 c.setParameters(params); 

Но он не влияет на итоговые данные EXIF, его все равно всегда 0

Я также пробовал эти решения, когда изображение поворачивается после его взятия: значение тега ориентации EXIF ​​всегда 0 для изображения, сделанного с помощью приложения для портретов портретирования

И пока это поворачивает фотографию, ориентация EXIF ​​все равно всегда 0.

Я также попытался напрямую установить данные EXIF: как сохранить данные Exif после сжатия растрового изображения в Android

 private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { final File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE, ""); try { FileOutputStream fos = new FileOutputStream(pictureFile); ExifInterface exif = new ExifInterface(pictureFile.toString()); exif.setAttribute(ExifInterface.TAG_ORIENTATION, "3"); exif.saveAttributes(); fos.write(data); fos.close(); //upload photo.. } } } 

Но EXIF ​​Orientation по-прежнему 0 после загрузки.

Я также рассмотрел эти решения:

Данные Exif TAG_ORIENTATION всегда 0

Как написать exif данные для изображения в Android?

Как получить правильную ориентацию изображения, выбранного из галереи изображений по умолчанию

Как установить ориентацию изображения на фото?

Но все они связаны с корректировкой ориентации путем вращения, что не влияет на данные EXIF, или напрямую устанавливает данные EXIF, которые, похоже, не работают.

Как изменить данные ориентации EXIF ​​файла от 0 до 3?

ОБНОВИТЬ:

Вот мой код загрузки:

 Bitmap sBitmap = null; final File sResizedFile = getOutputMediaFile(MEDIA_TYPE_IMAGE, "_2"); try { sBitmap = BitmapFactory.decodeStream(new FileInputStream(pictureFile), null, options); } catch (FileNotFoundException e) { Log.e("App", "[MainActivity] unable to convert pictureFile to bitmap"); e.printStackTrace(); return; } // ... compute sw and sh int values Bitmap sOut = Bitmap.createScaledBitmap(sBitmap, sw, sh, false); Bitmap rotatedBitmap = rotateBitmap(sOut, 3); FileOutputStream sfOut; try { sfOut = new FileOutputStream(sResizedFile); rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 70, sfOut); sfOut.flush(); sfOut.close(); sBitmap.recycle(); sOut.recycle(); rotatedBitmap.recycle(); } catch (Exception e) { Log.e("App", "[MainActivity] unable to save thumbnail"); e.printStackTrace(); return; } // upload small thumbnail TransferObserver sObserver = transferUtility.upload( "stills/small", /* The bucket to upload to */ filename + ".jpg", /* The key for the uploaded object */ sResizedFile /* The file where the data to upload exists */ ); 

Solutions Collecting From Web of "Данные Android EXIF ​​всегда 0, как его изменить?"

Как вы можете видеть, информация EXIF ​​не надежна на Android (особенно устройства Samsung).

Однако телефонная база данных SQL, содержащая ссылки на объект Media, надежна. Я бы предложил пойти этим путем.

Получение ориентации от Uri:

 private static int getOrientation(Context context, Uri photoUri) { Cursor cursor = context.getContentResolver().query(photoUri, new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null); if (cursor.getCount() != 1) { cursor.close(); return -1; } cursor.moveToFirst(); int orientation = cursor.getInt(0); cursor.close(); cursor = null; return orientation; } 

Затем инициализируйте повернутое Bitmap :

 public static Bitmap rotateBitmap(Context context, Uri photoUri, Bitmap bitmap) { int orientation = getOrientation(context, photoUri); if (orientation <= 0) { return bitmap; } Matrix matrix = new Matrix(); matrix.postRotate(orientation); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); return bitmap; } 

Если вы хотите изменить ориентацию изображения, попробуйте следующий фрагмент:

 public static boolean setOrientation(Context context, Uri fileUri, int orientation) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.ORIENTATION, orientation); int rowsUpdated = context.getContentResolver().update(fileUri, values, null, null); return rowsUpdated > 0; } 

Если вы зададите ориентацию изображения, в дальнейшем он будет постоянно установлен в правильной ориентации. Необходимо использовать ExifInterface позже, потому что изображение уже повернуто надлежащим образом.

Если этот метод не является удовлетворительным, вы можете попробовать этот метод

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

«Тем не менее …» в вашем ответе предлагает, пока вы знаете причину, у вас нет исправления.

Оказывается, мой код смог установить данные EXIF, но есть расхождение между тем, как Android интерпретирует эти данные и как IOS … интерпретирует его.

Это может быть проблемой, стоящей перед нами. Вы можете попробовать вручную изменить настройку Endianness Exif, открыв jpeg в шестнадцатеричном редакторе и найдя …

  • Байты 45 78 69 66 (делает текст «Exif»), а затем два нулевых байта 00 00 .
  • Тогда это должно быть 49 49 (делает текст «II»), что означает чтение данных как минимальный формат.
  • Если вы замените его на 4D 4D (или «MM» текст), то сторона чтения будет рассматривать данные как большие endian.

Проверьте это в iOS, чтобы узнать, правильны ли цифры.

И в отношении этого …

Тем не менее, установка 3 отображается как 0 на iOS, а изображение находится в стороне от Chrome.
Установка 6 отображается как 3 на iOS, и изображение выглядит правильно в Chrome.

Единственное, что я могу добавить, это то, что iOS Mac – Big Endian *, а Android / PC – Little Endian . По сути, Little Endian читает / записывает байты как справа налево, в то время как Big Endian противоположна.

В двоичном формате: 011 означает 3 и 110 средство 6 . Разница между 3 и 6 – это просто порядок чтения этих бит единиц и нулей. Таким образом, система, которая читает как « zero-one-one получает результат 3, а другая система Endian будет читать байт с такими же битами, как one-one-zero и скажет, что результатом является 6 . Я не могу объяснить, почему «3 отображается как 0» без тестового файла для анализа байтов, но для меня это странный результат.

</end rant>
<sleep>

* Note : В то время как Mac – Big Endian, двойная проверка говорит, что iOS использует систему Little Endian в конце концов. Тем не менее, ваши номера по-прежнему указывают на проблему «Большой против маленького».

Оказывается, мой код смог установить данные EXIF, но существует расхождение между тем, как Android интерпретирует эти данные и как интерпретирует его iOS и Chrome на Mac (где я проверял результирующий файл).

Это единственный код, необходимый для установки ориентации EXIF:

 ExifInterface exif = new ExifInterface(pictureFile.toString()); exif.setAttribute(ExifInterface.TAG_ORIENTATION, "3"); exif.saveAttributes(); 

Тем не менее, установка 3 отображается как 0 на iOS, а изображение находится в стороне от Chrome.

Установка 6 отображается как 3 на iOS, и изображение выглядит правильно в Chrome.

Обратитесь к проекту GitHub https://github.com/pandiaraj44/Camera . Он имеет пользовательскую активность камеры, где EXIF ​​TAG_ORIENTATION обрабатывается правильно. Вы можете клонировать проект и проверять его. Подробные сведения о кодах см. На странице https://github.com/pandiaraj44/Camera/blob/master/app/src/main/java/com/pansapp/cameraview/CameraFragment.java.

Существует один класс для чтения и обновления данных изображений.

Чтобы обновить атрибуты, вы можете использовать это

 ExifInterface ef = new ExifInterface(filePath); ef.setAttribute(MAKE_TAG, MAKE_TAG); ef.setAttribute(ExifInterface.TAG_ORIENTATION, orientation+""); ef.saveAttributes(); 

И для чтения вы можете так использовать

  ExifInterface exif = null; try { exif = new ExifInterface(absolutePath+path); } catch (IOException e) { e.printStackTrace(); } int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); 

Надеюсь, это поможет вам