Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
[camera] android-rework part 4: Android flash and zoom features (#3798)
Browse files Browse the repository at this point in the history
* Base classes to support Android camera features

Co-authored-by: Andrew Coutts <[email protected]>

* Fixed formatting

* Applied feedback from PR

* Added Android Flash and Zoom features

Co-authored-by: Andrew Coutts <[email protected]>

* Use mockito-inline

* Fix formatting issue

* Processed feedback on pull request.

* Fixed formatting

* Fixed formatting

* Swap docs to match correct methods

Co-authored-by: Andrew Coutts <[email protected]>
  • Loading branch information
mvanbeusekom and acoutts authored May 25, 2021
1 parent 3b0f897 commit 2576d6b
Show file tree
Hide file tree
Showing 8 changed files with 627 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/camera/camera/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ android {
dependencies {
compileOnly 'androidx.annotation:annotation:1.1.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:3.5.13'
testImplementation 'org.mockito:mockito-inline:3.5.13'
testImplementation 'androidx.test:core:1.3.0'
testImplementation 'org.robolectric:robolectric:4.3'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.camera.features.flash;

import android.hardware.camera2.CaptureRequest;
import io.flutter.plugins.camera.CameraProperties;
import io.flutter.plugins.camera.features.CameraFeature;

/** Controls the flash configuration on the {@link android.hardware.camera2} API. */
public class FlashFeature extends CameraFeature<FlashMode> {
private FlashMode currentSetting = FlashMode.auto;

/**
* Creates a new instance of the {@link FlashFeature}.
*
* @param cameraProperties Collection of characteristics for the current camera device.
*/
public FlashFeature(CameraProperties cameraProperties) {
super(cameraProperties);
}

@Override
public String getDebugName() {
return "FlashFeature";
}

@Override
public FlashMode getValue() {
return currentSetting;
}

@Override
public void setValue(FlashMode value) {
this.currentSetting = value;
}

@Override
public boolean checkIsSupported() {
Boolean available = cameraProperties.getFlashInfoAvailable();
return available != null && available;
}

@Override
public void updateBuilder(CaptureRequest.Builder requestBuilder) {
if (!checkIsSupported()) {
return;
}

switch (currentSetting) {
case off:
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
break;

case always:
requestBuilder.set(
CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
break;

case torch:
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
break;

case auto:
requestBuilder.set(
CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
break;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.camera.features.flash;

// Mirrors flash_mode.dart
public enum FlashMode {
off("off"),
auto("auto"),
always("always"),
torch("torch");

private final String strValue;

FlashMode(String strValue) {
this.strValue = strValue;
}

public static FlashMode getValueForString(String modeStr) {
for (FlashMode value : values()) {
if (value.strValue.equals(modeStr)) return value;
}
return null;
}

@Override
public String toString() {
return strValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.camera.features.zoomlevel;

import android.graphics.Rect;
import android.hardware.camera2.CaptureRequest;
import io.flutter.plugins.camera.CameraProperties;
import io.flutter.plugins.camera.features.CameraFeature;

/** Controls the zoom configuration on the {@link android.hardware.camera2} API. */
public class ZoomLevelFeature extends CameraFeature<Float> {
private static final float MINIMUM_ZOOM_LEVEL = 1.0f;
private final boolean hasSupport;
private final Rect sensorArraySize;
private Float currentSetting = MINIMUM_ZOOM_LEVEL;
private Float maximumZoomLevel = MINIMUM_ZOOM_LEVEL;

/**
* Creates a new instance of the {@link ZoomLevelFeature}.
*
* @param cameraProperties Collection of characteristics for the current camera device.
*/
public ZoomLevelFeature(CameraProperties cameraProperties) {
super(cameraProperties);

sensorArraySize = cameraProperties.getSensorInfoActiveArraySize();

if (sensorArraySize == null) {
maximumZoomLevel = MINIMUM_ZOOM_LEVEL;
hasSupport = false;
return;
}

Float maxDigitalZoom = cameraProperties.getScalerAvailableMaxDigitalZoom();
maximumZoomLevel =
((maxDigitalZoom == null) || (maxDigitalZoom < MINIMUM_ZOOM_LEVEL))
? MINIMUM_ZOOM_LEVEL
: maxDigitalZoom;

hasSupport = (Float.compare(maximumZoomLevel, MINIMUM_ZOOM_LEVEL) > 0);
}

@Override
public String getDebugName() {
return "ZoomLevelFeature";
}

@Override
public Float getValue() {
return currentSetting;
}

@Override
public void setValue(Float value) {
currentSetting = value;
}

@Override
public boolean checkIsSupported() {
return hasSupport;
}

@Override
public void updateBuilder(CaptureRequest.Builder requestBuilder) {
if (!checkIsSupported()) {
return;
}

final Rect computedZoom =
ZoomUtils.computeZoom(
currentSetting, sensorArraySize, MINIMUM_ZOOM_LEVEL, maximumZoomLevel);
requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, computedZoom);
}

/**
* Gets the minimum supported zoom level.
*
* @return The minimum zoom level.
*/
public float getMinimumZoomLevel() {
return MINIMUM_ZOOM_LEVEL;
}

/**
* Gets the maximum supported zoom level.
*
* @return The maximum zoom level.
*/
public float getMaximumZoomLevel() {
return maximumZoomLevel;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugins.camera.features.zoomlevel;

import android.graphics.Rect;
import androidx.annotation.NonNull;
import androidx.core.math.MathUtils;

/**
* Utility class containing methods that assist with zoom features in the {@link
* android.hardware.camera2} API.
*/
final class ZoomUtils {

/**
* Computes an image sensor area based on the supplied zoom settings.
*
* <p>The returned image sensor area can be applied to the {@link android.hardware.camera2} API in
* order to control zoom levels.
*
* @param zoom The desired zoom level.
* @param sensorArraySize The current area of the image sensor.
* @param minimumZoomLevel The minimum supported zoom level.
* @param maximumZoomLevel The maximim supported zoom level.
* @return An image sensor area based on the supplied zoom settings
*/
static Rect computeZoom(
float zoom, @NonNull Rect sensorArraySize, float minimumZoomLevel, float maximumZoomLevel) {
final float newZoom = MathUtils.clamp(zoom, minimumZoomLevel, maximumZoomLevel);

final int centerX = sensorArraySize.width() / 2;
final int centerY = sensorArraySize.height() / 2;
final int deltaX = (int) ((0.5f * sensorArraySize.width()) / newZoom);
final int deltaY = (int) ((0.5f * sensorArraySize.height()) / newZoom);

return new Rect(centerX - deltaX, centerY - deltaY, centerX + deltaX, centerY + deltaY);
}
}
Loading

0 comments on commit 2576d6b

Please sign in to comment.