Как стать автором
Обновить
75.71
Huawei
Huawei – мировой лидер в области ИКТ

Работа с камерой на платформе HMS: улучшаем качество съёмки и добавляем различные режимы в свои приложения

Время на прочтение 12 мин
Количество просмотров 4.3K
Привет, Хабр! Пользователям смартфонов HUAWEI и HONOR по умолчанию доступно большое количество режимов и эффектов съёмки: ночная съёмка, распознавание сцен, HDR, широкая диафрагма и т. д. С помощью набора инструментов Camera Engine эти и другие режимы можно добавить в любое приложение. Под катом расскажу о возможностях этого SDK и покажу, как по максимуму использовать камеру.

Интеграция Camera Engine



Camera Engine — это SDK с предварительно настроенными режимами съёмки для простой интеграции в сторонние IDE. Для разработки приложений, совместимых с Camera Engine, рекомендуется использовать Android Studio версии не ниже 3.0.1. Они будут работать на телефонах Huawei с процессором Kirin 980 или новее и ОС не старше EMUI 10.0.

Для начала необходимо зарегистрироваться в качестве разработчика и пройти проверку личности на нашем портале для разработчиков. Подробнее об этом рассказывается в разделе регистрация Huawei ID. Помимо прочего, надо будет подписать соглашение о сотрудничестве — система автоматически предложит вам сделать это при загрузке SDK.

Подробнее о создании проекта и настройках читайте в нашем руководстве по интеграции.

Работа в общем режиме


Создаём режим Camera Kit, когда приложение запущено и доступен предварительный просмотр:

// It is recommended that exceptions be captured in the 1.0.1 version. In the 1.0.2 and later versions, exceptions do not need to be captured, but the CameraKit instance is obtained.
if (!isGetInstance) {
   try {
       mCameraKit = CameraKit.getInstance(getApplicationContext());
   } catch (NoSuchMethodError e) {
       Log.w(TAG, "this version camerakit does not contain VersionInfoInterface");
   } finally {
       isGetInstance = true;
   }
}
// If a mobile phone does not support CameraKit, or the CameraKit SDK version is incompatible with the capability layer, the return result is empty.
if (mCameraKit == null) {
   return;
}
// Query the camera list of the mobile phone. Currently, only the rear camera supports the super night mode.
String[] cameraLists = mCameraKit.getCameraIdList();
// Query the modes supported by the current cameras.
int[] modes = mCameraKit.getSupportedModes(cameraLists[0]);
// Create a mode.
mCameraKit.createMode(cameraLists[0], mCurrentModeType, mModeStateCallback, mCameraKitHandler);

Конфигурируем настройки в зависимости от характеристик режима и требований службы:

// Configure the preview surface.
modeConfigBuilder.addPreviewSurface(surface);
// Set photographing parameters.
modeConfigBuilder.addCaptureImage(mCaptureSize, ImageFormat.JPEG)
// Configure the action data listener.
modeConfigBuilder.setDataCallback(actionDataCallback, mCameraKitHandler);
// Configure the action status listener.
modeConfigBuilder.setStateCallback(actionStateCallback, mCameraKitHandler);
// Configure the mode.
mMode.configure();

Предварительный просмотр запускается, когда с помощью mode status callback возвращается mode configuration success:

mMode.startPreview();

Установка функциональных параметров:

// Query the functions supported by the mode.
List<CaptureRequest.Key<?>> parameters = mModeCharacteristics.getSupportedParameters();
// Set zoom.
int zoomSetResult = mMode.setZoom(level);

Камера будет делать снимок после касания UI:

// In this example, the portrait mode is used by default, which simplifies the rotation angle setting logic.
mMode.setImageRotation(90);
// This example uses the default photo storage path.
mFile = new File(getExternalFilesDir(null), "pic.jpg");
// Take a photo. The photo is asynchronously called back through ActionDataCallback.onImageAvailable.
mMode.takePicture();

Функция обратного вызова используется в режиме создания статуса режима и процессов управления:

private final ModeStateCallback mModeStateCallback = new ModeStateCallback() {
   @Override
   public void onCreated(Mode mode) {
       // Configure the mode after the mode is created successfully.
   }
   @Override
   public void onConfigured(Mode mode) {
       // Start the preview after the mode is configured successfully.
   }
   // ...
};

Обратный вызов данных действий используется для их асинхронной обработки. Например, уведомляем приложение о формате, в котором создаётся фото:

private final ActionDataCallback = new ActionDataCallback() {
   @Override
   public void onImageAvailable(Mode mode, @Type int type, Image image) {
       // Store photos.
   }
};

Обратный вызов состояния действия используется для его асинхронной обработки — например, начала предварительного просмотра, начала или остановки фотографирования:

private final ActionStateCallback = new ActionStateCallback() {
   @Override
   public void onPreview(Mode mode, int state, PreviewResult result) {
       // Preview starting callback.
   }
   @Override
   public void onTakePicture(Mode mode, int state, TakePictureResult result) {
       // Photographing action callback.
   }
};

Когда приложение закрывается, занятые ресурсы высвобождаются:

mMode.release();

Работа с режимом ночной съёмки



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

Для работы в этом режиме установите для mCurrentModeType значение Mode.Type.SUPER_NIGHT_MODE. Дальше — как в общем режиме, только после запуска предварительного просмотра установите чувствительность и время экспозиции, чтобы настроить пользовательский интерфейс (UI) приложения. Если эти параметры не заданы, используются настройки по умолчанию.

Ниже приведён метод установки чувствительности камеры; метод установки экспозиции (RequestKey.HW_SUPER_NIGHT_EXPOSURE) аналогичен.

// Query the functions supported by the mode.
List<CaptureRequest.Key<?>> parameters = mModeCharacteristics.getSupportedParameters();
// If the sensitivity can be set
if ((parameters != null) && (parameters.contains(RequestKey.HW_SUPER_NIGHT_ISO))) {
   // Query the supported sensitivity range.
   List<Long> values = mModeCharacteristics.getParameterRange(RequestKey.HW_SUPER_NIGHT_ISO);
   // Set the first sensitivity parameter.
   mMode.setParameter(RequestKey.HW_SUPER_NIGHT_ISO, values.get(0));
}

Можно с помощью касания пользовательского интерфейса остановить экспозицию и сделать фотографии. Вызов API для остановки фотографирования:

mMode.stopPicture();

Обратный вызов состояния действия используется для его асинхронной обработки — например, начала предварительного просмотра, начала или остановки фотографирования:

private final ActionStateCallback = new ActionStateCallback() {
   @Override
   public void onPreview(Mode mode, int state, PreviewResult result) {
       // Preview starting callback.
   }
   @Override
   public void onTakePicture(Mode mode, int state, TakePictureResult result) {
       // Photographing action callback.
       switch (state) {
           case TakePictureResult.State.CAPTURE_STARTED:
               Log.d(TAG, "onState: STATE_CAPTURE_STARTED");
               break;
           case TakePictureResult.State.CAPTURE_EXPOSURE_BEGIN:
               /* When the long-time exposure mode is enabled, use the result class to obtain the exposure time required for the super night mode.
                  After receiving the exposure time return using the callback, you can call stopPicture to stop the exposure before the exposure time ends. */
               break;
           case TakePictureResult.State.CAPTURE_EXPOSURE_END:
               // The long-time exposure ends. When the exposure ends at the specified time or in advance, this status is called back.
               break;
           case TakePictureResult.State.CAPTURE_COMPLETED:
               // Photographing is complete.
               break;
           default:
               break;
       }
   }
};

Работа с режимом широкой диафрагмы



Широкая диафрагма — режим, в котором фон размывается, а объект на изображении становится подчёркнуто чётким, выделенным.

Для работы устанавливаем для mCurrentModeType значение Mode.Type.BOKEH_MODE. После запуска предварительного просмотра задаём параметры диафрагмы:

// Query the functions supported by the mode.
List<CaptureRequest.Key<?>> parameters = mModeCharacteristics.getSupportedParameters();
// If the ultra-wide angle function is supported,
if ((parameters != null) && (parameters.contains(RequestKey.HW_APERTURE))) {
   // Query the supported ultra-wide angle level range.
   List<Float> values = mModeCharacteristics.getParameterRange(RequestKey.HW_APERTURE);
   // Set the first ultra-wide angle parameter.
   mMode.setParameter(RequestKey.HW_APERTURE, vales.get(0));
}

Работа с видео


В этом режиме можно применять к записи эффекты в реальном времени. Например, функция AI movie позволяет настроить желаемые яркость и насыщенность, наложить эффект плёнки и т. д., чтобы не тратить время на постобработку.

Для работы в режиме для mCurrentModeType устанавливаем значение Mode.Type.VIDEO_MODE, задаём параметры:

// Configure the preview surface.
modeConfigBuilder.addPreviewSurface(surface);
// Configure the recording surface.
modeConfigBuilder.addVideoSurface(videoSurface);
// Set photographing parameters.
modeConfigBuilder.addCaptureImage(mCaptureSize, ImageFormat.JPEG)
// Configure the action data listener.
modeConfigBuilder.setDataCallback(actionDataCallback, mCameraKitHandler);
// Configure the action status listener.
modeConfigBuilder.setStateCallback(actionStateCallback, mCameraKitHandler);
// Configure the mode.
mMode.configure();

После запуска предварительного просмотра запрашиваем и настраиваем поддерживаемые функции, например AI movie:

// Query the functions supported by the mode.
List<CaptureRequest.Key<?>> parameters = mModeCharacteristics.getSupportedParameters();
// If the AI movie feature is supported,
(parameters != null) && (parameters.contains(RequestKey.HW_AI_MOVIE))
// Query the supported range of the AI movie feature.
List<Byte> lists = modeCharacteristics.getParameterRange(RequestKey.HW_AI_MOVIE)
// Set the AI movie feature parameter.
mMode.setParameter(RequestKey.HW_AI_MOVIE, value)

После запуска предварительного просмотра вызываем API записи видео:

// Start recording.
mMode.startRecording()
mMediaRecorder.start();
// Pause recording.
mMode.pauseRecording();
mMediaRecorder.pause();
// Resume recording.
mMode.resumeRecording();
mMediaRecorder.resume();
// Stop recording.
mMode.stopRecording();
mMediaRecorder.stop();

Всё остальное — как при работе в общем режиме.

Работа с режимом HDR



HDR (High Dynamic Range) — режим для съёмки с недостаточным освещением. Он объединяет несколько снимков одного кадра с разной выдержкой и тем самым повышает чёткость изображения. 

Для интеграции в приложение установите для mCurrentModeType значение Mode.Type.HDR_MODE. Всё остальное — как при работе с общим режимом.

Работа с режимами замедления


Режимы замедления — Slow-mo и Super slow-mo — позволяют записать видео с частотой 60 fps, 120 fps, 480 fps или 960 fps.

Для работы в режиме Slow-mo задаём mCurrentModeType как Mode.Type.SLOW_MOTION_MODE. 

// Set the recording frame rate.
modeConfigBuilder.setVideoFps(recordFps);

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

// Start recording.
mMode.startRecording()
// Stop recording.
mMode.stopRecording()

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

Для работы в Super slow-mo устанавливаем для mCurrentModeType значение Mode.Type.SUPER_SLOW_MOTION.

// Start recording.
mMode.startRecording()
// Stop recording.
mMode.stopRecording()

Эти два элемента конфигурации должны быть установлены попарно на основе Map, возвращаемой modeCharacteristics.getSupportedVideoSizes (). Режим фото не поддерживается, поэтому не следует добавлять связанную с ним конфигурацию.

Разрешение видео должно быть таким же, как разрешение при предварительном просмотре. Ниже приведены различные операции в режиме Super slow-mo. Используйте следующие API:

// Obtain the motion detection area.
modeCharacteristics.getParameterRange(RequestKey.HW_SUPER_SLOW_CHECK_AREA)

Возвращается диапазон в центральной системе координат:

// Start recording.
Mode.startRecording(file);

Если требуется ручной режим записи, вызовите mMode.startRecording (file) напрямую. Запись нельзя поставить на паузу.

Чтобы Super slow-mo работал в автоматическом режиме, сначала задаём кадр обнаружения движения:

mMode.setParameter(RequestKey.HW_SUPER_SLOW_CHECK_AREA,rect);

Рамка обнаружения должна быть прямоугольной, преобразованной в центральную систему координат из системы координат предварительного просмотра. В качестве вершины принимаем верхний левый угол превью. Правило определения длины края кадра выглядит следующим образом: на телефоне, поддерживающем 7680 кадров в секунду, длина края кадра может быть установлена ​​на значение в диапазоне [1/3, 1] от меньшей стороны экрана телефона. В противном случае может быть доставлено только фиксированное значение, которое составляет 1/3 от меньшей стороны.

Модуль работает в автоматическом режиме и вызывается mMode.startRecording(file). До обнаружения движущегося объекта, то есть до того, как будет возвращён RecordingResult.State.RECORDING_STARTED, можно вызвать mMode.stopRecording (), чтобы остановить запись. После обнаружения движущегося объекта запись не может быть остановлена. 

Когда вызывается mMode.stopRecording (), возвращается событие RecordingResult.State.RECORDING_STOPPED. После однократной записи режим переключается на ручной. Чтобы снова выполнить автоматическую запись, доставляем зону обнаружения.

// Action status callback.
class ModeActionStateCallback extends ActionStateCallback {
   @Override
   public void onRecording(Mode mode, int state, RecordingResult result) {
       switch (state) {
           // An IO error occurs.
           case RecordingResult.State.ERROR_FILE_IO:
           // An unknown error occurs.
           case RecordingResult.State.ERROR_UNKNOWN:
           //The bottom-layer initialization is not ready.
           case RecordingResult.State.ERROR_RECORDING_NOT_READY:
               break;
           // The bottom layer is ready.
           case RecordingResult.State.RECORDING_READY:
               break;
           // Recording is started. This parameter is returned only in automatic mode.
           case RecordingResult.State.RECORDING_STARTED:
               break;
           // Recording is stopped.
           case RecordingResult.State.RECORDING_STOPPED:
               break;
           // Recording is complete.
           case RecordingResult.State.RECORDING_COMPLETED:
               break;
           // The recorded file is saved.
           case RecordingResult.State.RECORDING_FILE_SAVED:
               break;
           default:
               break;
       }
   }
}

Super slow-mo поддерживает вспышку, зум и автофокус, не поддерживается фронтальной камерой.

Работа с режимом портретной съёмки



Режим портретной съёмки работает с основной и фронтальной камерой, позволяет обнаружить на изображении различные объекты: лица, улыбки и др. Пользователь может выбрать и применить эффекты освещения.

Для работы установим для mCurrentModeType значение Mode.Type.PORTRAIT_MODE. Остальные шаги — как в общем режиме, только после запуска предварительного просмотра задаём настройки для портретного режима:

// Query the facial beautification functions supported by the mode.
modeCharacteristics.getSupportedBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_SMOOTH)
modeCharacteristics.getSupportedBeauty(Metadata.BeautyType.HW_BEAUTY_FACE_SLENDER)
modeCharacteristics.getSupportedBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_COLOR)
modeCharacteristics.getSupportedBeauty(Metadata.BeautyType.HW_BEAUTY_BODY_SHAPING)
// Configure the facial beautification functions.
mMode.setBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_SMOOTH, value)
mMode.setBeauty(Metadata.BeautyType.HW_BEAUTY_FACE_SLENDER, value)
mMode.setBeauty(Metadata.BeautyType.HW_BEAUTY_SKIN_COLOR, value)
mMode.setBeauty(Metadata.BeautyType.HW_BEAUTY_BODY_SHAPING, value

Работа с режимом Pro



Режим Pro работает как с фото, так и с видео. При использовании этого API появляется возможность изменить ISO и продолжительность экспозиции, режим фокусировки и так далее. Кроме того, режим Pro поддерживает вспышку, зум, автофокус, режим цветокоррекции и распознавание лиц. Не работает с фронтальной камерой.

В режиме Pro новые параметры открываются в виде ключей. Нам нужно только:

  1. Установить для mCurrentModeType значение PRO_PHOTO_MODE или PRO_VIDEO_MODE.
  2. Использовать mCurrentModeType для создания объекта Mode.
  3. Вызвать метод setParameter объекта Mode, чтобы включить соответствующую возможность.
  4. Использовать TakePicture, startRecording и методы stopRecording объекта Mode для фотосъёмки и записи видео.

После включения функции предварительного просмотра можно настроить параметры режима Pro.

// Query the functions supported by the mode.
List<CaptureRequest.Key<?>> parameters = mModeCharacteristics.getSupportedParameters();
// Query the supported ISO range.
List<Integer> values = mModeCharacteristics.getParameterRange(RequestKey.HW_PRO_SENSOR_ISO_VALUE);
// Set the ISO value. The first value is used as an example.
mMode.setParameter(RequestKey.HW_ PRO_SENSOR_ISO_VALUE, values.get(0));

Настройки других параметров аналогичны. Чтобы включить автоматический режим, для ISO и экспозиции выставляем значение 0. Надо учитывать, что режим Pro не поддерживает фронтальную камеру и серийную съёмку.

// Deliver the parameters.
mMode.setParameter();
// Start shooting.
mMode.takePicture()

Чтобы сделать снимок в формате RAW, используем getSupportedCaptureSizes (ImageFormat.RAW_SENSOR) в ModeCharacteristics. Чтобы запросить поддерживаемое разрешение, выбираем разрешение captureSize и вызываем addCaptureImage (captureSize, ImageFormat.RAW_SEOSOR) из ModeConfig.Builder.

modeConfigBuilder.addCaptureImage(captureSize,ImageFormat.RAW_SENSOR)

Доставка параметров при работе в режиме Pro video:

// Deliver the parameters.
mMode.setParameter();


После включения функции предварительного просмотра вызываем API записи. Параметры — как в Pro foto, за исключением выдержки.

// Start recording.
mMode.startRecording()
mMediaRecorder.start();
// Pause recording.
mMode.pauseRecording();
mMediaRecorder.pause();
// Resume recording.
mMode.resumeRecording();
mMediaRecorder.resume();
// Stop recording.
mMode.stopRecording();
mMediaRecorder.stop();

Работа с нормальным режимом


В нормальном режиме можно активировать ИИ-функции из арсенала ML Kit. С их помощью можете, например, научить приложение распознавать сценарии, чтобы автоматически применять соответствующие параметры цвета, яркости и контрастности. Наши сервисы искусственного интеллекта определяют более 1500 сцен из 25 категорий: объекты архитектуры, домашние животные, растения, автомобили и пр.

Для активации нормального режима установите для mCurrentModeType значение Mode.Type.NORMAL_MODE. После включения предварительного просмотра задаём параметры. Ниже — пример для интеллектуального определения сценариев:

// Query whether the AI capability is supported. If true is returned, AI scenario identification is supported.
modeCharacteristics. getSupportedSceneDetection();
// Enable AI scene identification. You can disable it afterwards by setting the input parameter to false.
mMode. setSceneDetection (true);
// Identify the scene and perceive the identified scene based on the callback information.
class ModeActionStateCallback extends ActionStateCallback {
   @Override
   public void onSceneDetection(Mode mode, @SceneDetectionResult.State int state,
       @Nullable SceneDetectionResult result) {
       // Confirm the effect of the scene to be enabled. For example, the scene "flower" is identified here.
       // After the scene is enabled, the parameters are adjusted to make the flowers look brighter.
       mMode.setParameter(RequestKey.HW_SCENE_EFFECT_ENABLE, true);
   }
}

// Disable the scene effects. If the scene effect is enabled and then disabled, parameter adjustment will be canceled.
mMode.setParameter(RequestKey.HW_SCENE_EFFECT_ENABLE, false);

Спортивная съёмка (burst shooting) с помощью основной камеры:

// Query whether burst shooting is supported. If true is returned, burst shooting is supported.
modeCharacteristics. isBurstSupported();
// Start burst shooting.
mMode. takePictureBurst();

Или: 

mMode. takePictureBurst (filename);
// Stop burst shooting.
mMode.stopPicture();



На этом пока всё. Если у вас есть вопросы по работе с камерой на платформе HMS, можете задать их в комментариях.
Теги:
Хабы:
+13
Комментарии 5
Комментарии Комментарии 5

Публикации

Информация

Сайт
huawei.ru
Дата регистрации
Дата основания
1987
Численность
свыше 10 000 человек
Местоположение
Россия