This repository has been archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[camera] android-rework part 4: Android flash and zoom features (#3798)
* 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
1 parent
3b0f897
commit 2576d6b
Showing
8 changed files
with
627 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
...a/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashFeature.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...mera/camera/android/src/main/java/io/flutter/plugins/camera/features/flash/FlashMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
.../android/src/main/java/io/flutter/plugins/camera/features/zoomlevel/ZoomLevelFeature.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
.../camera/android/src/main/java/io/flutter/plugins/camera/features/zoomlevel/ZoomUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.