Поддержка камер на различных форм-факторах

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

Рисунок 1. Пример работы приложений камеры на разных дисплеях.

Почему ломается логика телефона

Приложения камеры часто делают предположения, которые приводят к критическим сбоям в средах с различными форм-факторами.

Естественная ориентация

  • Предположение: Естественная ориентация устройства ROTATION_0 всегда портретная.
  • В реальности: на планшетах, внутреннем дисплее некоторых складных устройств и настольных мониторах ROTATION_0 часто отображается в альбомной ориентации.
  • Результат: Предварительный просмотр некорректно повернут на 90 градусов.
Рисунок 2. Видоискатель камеры до и после применения правильного поворота.

выравнивание датчика

  • Предположение: Длинная сторона датчика камеры совпадает с длинной стороной экрана.
  • В реальности: окно с изменяемым размером может быть квадратным или альбомным, в то время как датчик остается неподвижным (обычно 4:3).
  • Результат: Растянутые или иным образом искаженные изображения.
Рисунок 3. Видоискатель камеры до и после применения правильного масштабирующего коэффициента.

Плотность и размер экрана

  • Предположение: плотность и размер экрана не изменяются во время выполнения программы.
  • Реальность: В настольных средах пользователи могут свободно изменять размер окон.
  • Результат: Перезапуск сеанса работы с камерой при каждом перетаскивании нарушает удобство использования и может привести к сбоям.

Решение 1: Использование системных интентов

Если вашему приложению необходимо сделать фото или видео, но не требуется специальный пользовательский интерфейс камеры, лучший способ обработки различных форм-факторов — запустить предустановленную системную камеру устройства (см. Интенты камеры ).

Использование системного намерения перекладывает весь процесс захвата изображения на приложение камеры, разработанное производителем устройства (OEM). Это фактически перекладывает на аутсорсинг сложность поддержки форм-фактора, включая:

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

  • Доступ к расширенным аппаратным функциям — приложения для камер от производителей оборудования имеют эксклюзивный доступ к алгоритмам, оптимизированным для работы с оборудованием (ночной режим, HDR, переключение конкретных объективов), которые сложно или невозможно воспроизвести вручную.

Решение 2: Используйте Jetpack CameraX

CameraX — это библиотека Jetpack, созданная для упрощения разработки приложений для работы с камерой. CameraX учитывает жизненный цикл устройства и ориентирована на поверхность. В отличие от Camera2, которая требует ручного пересчета ориентации сенсора и размеров поверхности при каждом складывании, повороте или изменении размера устройства, CameraX автоматически обрабатывает переконфигурацию сеансов камеры во время изменения размера нескольких окон или при переходе приложения на подключенный дисплей, обеспечивая адаптацию потока предварительного просмотра без заиканий и искажений.

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

Сочинить

В Jetpack Compose используйте специальную библиотеку androidx.camera:camera-compose . Эта библиотека предоставляет компонент CameraXViewfinder , специально разработанный для обработки сложной геометрии, включая изменение размера, вращение и соотношение сторон, в рамках жизненного цикла Compose.

Компонент CameraXViewfinder устраняет наиболее распространенные источники ошибок в приложениях для работы с камерой:

  • Автоматическое преобразование координат — Одна из самых сложных задач при разработке приложения для камеры — это сопоставление касания пользователя (координаты x, y на экране) с системой координат датчика камеры (0-1, 0-1 с поворотом) для фокусировки и замера экспозиции. CameraXViewfinder предоставляет CoordinateTransformer , который автоматически выполняет математические вычисления, даже при изменении размера окна или складывании устройства.
  • Корректное поведение компоновки — В отличие от SurfaceView или TextureView , CameraXViewfinder корректно работает с порядком отображения по оси Z в Compose. Вы можете накладывать элементы пользовательского интерфейса (кольца фокусировки, элементы управления) или применять модификаторы (скругление углов, анимация) без появления артефактов рендеринга.
  • Изменение размера и соотношения сторон : CameraXViewfinder внутренне обрабатывает логику обрезки по центру или подгонки по центру , гарантируя, что предварительный просмотр не будет растягиваться при изменении размера окна приложения до нестандартных соотношений сторон (например, в режиме разделенного экрана или оконного режима рабочего стола).

Мнения

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

Решение 3: Динамическая обработка ориентации и изменения размера.

При непосредственном использовании API платформы следует учитывать поворот экрана устройства, перезапуск активности и соотношение сторон.

Прекратите использовать поворот экрана устройства.

Не полагайтесь исключительно на Display#getRotation() или ориентацию физических датчиков для определения макета пользовательского интерфейса.

  • Используйте метрики окна — определите свою компоновку (альбомная или портретная) путем сравнения ширины и высоты окна приложения с помощью WindowManager#getCurrentWindowMetrics() .
  • Не обращайте внимания на естественную ориентацию — ваше приложение может отображаться в вертикальном окне на горизонтальном мониторе. Ориентация устройства не имеет значения для границ вашего пользовательского интерфейса.

Избегайте перезапуска активности

В Android по умолчанию активность вашего приложения прекращается при изменении конфигурации (например, при изменении размера окна). Для приложений камеры это проявляется в виде мерцания экрана или разрыва соединения во время видеозвонков.

  • Настройка манифеста — Укажите изменения конфигурации в манифесте , чтобы обрабатывать изменение размера без перезапуска.
  • Динамические обновления — В onConfigurationChanged() обновите параметры компоновки предварительного просмотра камеры в соответствии с новым размером окна.

Соотношение сторон и кадрирование

Распространенная проблема на складных устройствах и настольных компьютерах с Windows — это растягивание предварительного просмотра , когда изображение с камеры в формате 4:3 принудительно отображается в окне с соотношением сторон 16:9 или 1:1.

  • Не растягивайте изображение — никогда не пытайтесь точно подогнать буфер камеры под границы поля зрения, если соотношение сторон предварительного просмотра и окна различается.
  • Кадрирование по центру (рекомендуется): масштабируйте предварительный просмотр так, чтобы он заполнял кратчайшую сторону окна, и обрежьте лишнее. Это гарантирует, что объект останется неискаженным и заполнит кадр.
  • Подогнать по центру (альтернативный вариант): Если отображение всего поля зрения имеет решающее значение (например, при сканировании документа), сделайте предварительный просмотр с черными полосами внутри окна.
  • Подогнать по центру (альтернативный вариант): Если отображение всего поля зрения имеет решающее значение (например, при сканировании документа), сделайте предварительный просмотр с черными полосами внутри окна.

Бонус: Поддержка решений, изначально предназначенных для складных устройств.

Складные устройства — это не просто телефоны, которые можно согнуть; они предлагают уникальные аппаратные состояния, которые могут коренным образом улучшить качество фото- и видеосъемки. Вместо того чтобы рассматривать сгиб как проблему, которую нужно решить, используйте его для создания функций, недоступных на нескладных устройствах.

Режим «Настольный» (съемка без помощи рук)

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

Рисунок 5. Коммуникационное приложение в настольном режиме: видоискатель камеры расположен сверху шарнира, а элементы управления — снизу.

Режим заднего дисплея (селфи высокого качества)

  • На складных устройствах задние камеры, как правило, имеют более высокое качество, чем фронтальные. Режим заднего дисплея позволяет пользователю развернуть устройство и повернуть его, используя небольшой внешний экран в качестве видоискателя для основной задней камеры.
  • Режим отображения на задней панели позволяет делать селфи с разрешением более 50 Мп, сверхширокоугольные групповые снимки и высококачественные видеоблоги без необходимости носить с собой дополнительное оборудование.

Режим двух экранов (предварительный просмотр объекта)

  • Режим двух экранов позволяет одновременно отображать предварительный просмотр изображения с камеры на внутреннем и внешнем экранах. Это идеально подходит для фотосъемки людей: объекты съемки могут видеть себя на внешнем экране и корректировать свою позу, пока вы кадрируете снимок на внутреннем экране.
  • В отличие от режима отображения на заднем экране (в котором перемещается всё приложение целиком ), режим двух экранов создает дополнительное окно презентации на обложке.
Рисунок 5. Приложение камеры в режиме двух экранов.