Пример камеры на Android - PullRequest
       41

Пример камеры на Android

19 голосов
/ 09 декабря 2011

Я хочу написать действие, которое:

  1. Показывает предварительный просмотр камеры (видоискатель) и имеет кнопку «захват».
  2. Когда нажата кнопка «захват», делает снимок и возвращает его в вызывающее действие (setResult () & finish ()).

Существуют ли полные примеров, которые работают на каждыйустройство ?Ссылка на простое приложение с открытым исходным кодом, которое делает фотографии, была бы идеальным ответом.


Мои исследования до сих пор:

Это распространенный сценарий, иЕсть много вопросов и учебных пособий по этому вопросу.

Существует два основных подхода:

  1. Используйте событие android.provider.MediaStore.ACTION_IMAGE_CAPTURE.См. этот вопрос
  2. Используйте API-интерфейс камеры напрямую.См. этот пример или этот вопрос (с большим количеством ссылок) .

Подход 1 был бы идеальным, но проблема в том, что намерение реализованопо-разному на каждом устройстве. На некоторых устройствах это работает хорошо.Однако на некоторых устройствах вы можете сделать снимок, но он никогда не возвращается в ваше приложение.На некоторых устройствах ничего не происходит при запуске намерения. Обычно оно также сохраняет изображение на SD-карту и требует наличия SD-карты.Взаимодействие с пользователем также отличается на каждом устройстве.

При подходе 2 проблема заключается в стабильности.Я попробовал несколько примеров, но мне удалось остановить работу камеры (до перезагрузки) на некоторых устройствах и полностью заморозить другое устройство.На другом устройстве захват работал, но предварительный просмотр оставался черным.

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


Обновление:

Некоторое время я напрямую использовал API камеры.Это дает больше контроля (пользовательский интерфейс и т. Д.), Но я бы никому его не рекомендовал.Я работал бы на 90% устройств, но время от времени появлялось новое устройство с другой проблемой.

Некоторые проблемы, с которыми я столкнулся:

  • Обработка автофокуса
  • Обработка вспышки
  • Поддержка устройств с передней камерой, задней камерой или обоими
  • Каждое устройство имеет различную комбинацию разрешения экрана, разрешения предварительного просмотра (не всегдасоответствует разрешению экрана) и разрешению изображения.

Так что, в общем, я бы вообще не рекомендовал идти по этому маршруту, если нет другого пути.Через два года я сделал дамп с помощью пользовательского кода и вернулся к подходу, основанному на намерениях.С тех пор у меня было гораздо меньше проблем.Проблемы, которые у меня были с подходом, основанным на намерениях, в прошлом, вероятно, были просто моей собственной некомпетентностью.

Если вам действительно нужно идти по этому пути, я слышал, что это намного прощеесли вы поддерживаете только устройства с Android 4.0 +.

Ответы [ 3 ]

9 голосов
/ 10 декабря 2011

С подходом 2 проблема заключается в стабильности. Я попробовал несколько примеров, но мне удалось остановить работу камеры (до перезагрузки) на некоторых устройствах и полностью заморозить другое устройство. На другом устройстве захват работал, но предварительный просмотр оставался черным.

В примерах либо ошибка, либо проблема совместимости с устройствами.

1 голос
/ 10 декабря 2011

Пример, который дал CommonsWare, работает хорошо.Пример работает при использовании его как есть, но вот проблемы, с которыми я столкнулся при изменении его для моего варианта использования:

  1. Никогда не делайте второй снимок до того, как первый снимок будет завершен, другими словамиPictureCallback.onPictureTaken() был вызван.В примере CommonsWare для этой цели используется флаг inPreview.
  2. Убедитесь, что ваш SurfaceView полноэкранный.Если вы хотите меньший предварительный просмотр, вам может потребоваться изменить логику выбора размера предварительного просмотра, в противном случае предварительный просмотр может не соответствовать SurfaceView на некоторых устройствах.Некоторые устройства поддерживают только полноэкранный предварительный просмотр, поэтому его сохранение в полноэкранном режиме является самым простым решением.

Чтобы добавить дополнительные компоненты на экран предварительного просмотра, FrameLayout хорошо работает на моем опыте.Я начал с использования LinearLayout для добавления текста над предварительным просмотром, но это нарушило правило # 2.При использовании FrameLayout для добавления компонентов поверх предварительного просмотра у вас не возникает проблем с разрешением предварительного просмотра.

Я также опубликовал небольшую проблему, касающуюся Camera.open() в GitHub .

0 голосов
/ 25 февраля 2014

«рекомендуемый способ доступа к камере - открыть камеру в отдельном потоке» . В противном случае Camera.open () может занять некоторое время и привести к потере потока пользовательского интерфейса.

"Обратные вызовы будут вызываться в потоке событий open (int) был вызван из" . Вот почему для достижения максимальной производительности с помощью обратных вызовов предварительного просмотра камеры (например, для их кодирования в видео с низкой задержкой для живого общения) я рекомендую открыть камеру в новом HandlerThread, как показано здесь .

...