воскресенье, 21 сентября 2014 г.

Переворачиваем изображение после съемки на Android

Привет) И так, как я писал вчера, я хочу попробовать написать о маленьких решения, маленьких проблем с которыми я столкнулся при программировании. Итак я начинаю писать первую статью из серии.

Сегодня речь пойдет об обработке изображения полученного с камеры телефона. Проблема заключалась в следующем: при фотографировании при помощи приложения для камеры по умолчанию, при любой ориентации телефона фотографии получались повернутыми на 90 градусов (как при альбомной ориентации телефона). Проблема усугублялась тем, что этот эффект наблюдался не на всех устройствах. С такой ситуацией я столкнулся когда работал над приложением EnjoyingSelf.

Интересно как я с этим боролся? Тогда продолжай читать)



Для начала немного расскажу о приложении EnjoyingSelf. Приложение служит средством для оповещения своих друзей в facebook и twitter о моментах наслаждения своей жизни.



Очень важным для приложения это возможность сделать фотографию. Как я уже говорил, я использовал стандартное приложение камеры.

В Android для это можно сделать с помощью Intent:
   
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
        frag.startActivityForResult(cameraIntent, resultId);


MediaStore.ACTION_IMAGE_CAPTURE - Собственно обращение к приложению камеры по умолчанию
Сохраняем полученную фотографию в файле  imageFileUri


        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);

Последней строкой запускаем камеру и ждем ответ.

После того, как фотография была успешна сделана, мы возвращаемся в наше приложение. Теперь воспользуемся стандартными средствами Android для того чтобы получить картинку из файла:
   
        BitmapFactory.decodeFile(imageFileUri, options)


И вот, у меня на телефоне это работало как надо, но на другом изображение переворачивалось.

Что бы это исправить, нужно сначала узнать в какую сторону перевернуто изображение и повернуть его на нужный угол.

Первое что пришло мне в голову - определить положение телефона с помощью акселерометра.
Но тут меня ждало разочарование! Так как фото я делаю внешним приложением, то узнать положение телефона непосредственно в момент съемки я не могу, до съемка - нет смысла, остается только узнать сразу после съемки фото.

Для этого я воспользовался акселерометром. Но результаты меня не удовлетворили, так как было ошибочны! В мой голове уже промелькнула мысль делать кнопки для ручного поворота, но я случайно нагуглил другое (как оказалось удачное) решения.


Оказывается медиафайлы  могут хранить дополнительную информацию, комментирующую этот файл, описывающий условия и способы его получения и так далее, благодаря формату EXIF. Но нас интересует только один параметр - orientation.

Если orientation равен -1 - значит определить положение фотографии не удастся, если orientation > 0 - нужно проворачивать.
  
  if (orientation != 0){
       Matrix matrix = new Matrix();
       matrix.postRotate(orientation);
       bitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
  }
Все, после этого с помощью матрицы поворачиваем на нужный угол изображение и перезаписываем его.

Вот и все) Более подробно можно почитать тут.

По сути, я просто переписал готовое решение своими словами, однако я только начинаю и до описания уникальных проблем мне пока еще далеко!

Комментариев нет:

Отправить комментарий