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

[camera] Support JPEG fallback for Android on ImageStream #2870

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ Kazuki Yamaguchi <[email protected]>
Eitan Schwartz <[email protected]>
Chris Rutkowski <[email protected]>
Juan Alvarez <[email protected]>
Ogulcan Celik <[email protected]>
33 changes: 19 additions & 14 deletions packages/camera/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## 0.5.8+4

* Android: Added support for JPEG callback in image stream.

## 0.5.8+3

* Fix bug in usage example in README.md
* Fix bug in usage example in README.md

## 0.5.8+2

Expand Down Expand Up @@ -106,15 +110,14 @@

## 0.5.2

* Added capability to disable audio for the `CameraController`. (e.g. `CameraController(_, _,
enableAudio: false);`)
* Added capability to disable audio for the `CameraController`. (e.g. `CameraController(_, _, enableAudio: false);`)

## 0.5.1

* Can now be compiled with earlier Android sdks below 21 when
`<uses-sdk tools:overrideLibrary="io.flutter.plugins.camera"/>` has been added to the project
`AndroidManifest.xml`. For sdks below 21, the plugin won't be registered and calls to it will throw
a `MissingPluginException.`
`<uses-sdk tools:overrideLibrary="io.flutter.plugins.camera"/>` has been added to the project
`AndroidManifest.xml`. For sdks below 21, the plugin won't be registered and calls to it will throw
a `MissingPluginException.`

## 0.5.0

Expand Down Expand Up @@ -236,16 +239,18 @@ a `MissingPluginException.`
A lot of **breaking changes** in this version:

Getter changes:
- Removed `isStarted`
- Renamed `initialized` to `isInitialized`
- Added `isRecordingVideo`

* Removed `isStarted`
* Renamed `initialized` to `isInitialized`
* Added `isRecordingVideo`

Method changes:
- Renamed `capture` to `takePicture`
- Removed `start` (the preview starts automatically when `initialize` is called)
- Added `startVideoRecording(String filePath)`
- Removed `stop` (the preview stops automatically when `dispose` is called)
- Added `stopVideoRecording`

* Renamed `capture` to `takePicture`
* Removed `start` (the preview starts automatically when `initialize` is called)
* Added `startVideoRecording(String filePath)`
* Removed `stop` (the preview stops automatically when `dispose` is called)
* Added `stopVideoRecording`

## 0.1.2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class Camera {
private final Size captureSize;
private final Size previewSize;
private final boolean enableAudio;
private final int imageFormat;

private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSession;
Expand Down Expand Up @@ -77,14 +78,20 @@ public Camera(
final DartMessenger dartMessenger,
final String cameraName,
final String resolutionPreset,
final boolean enableAudio)
final boolean enableAudio,
final int imageFormat)
throws CameraAccessException {
if (activity == null) {
throw new IllegalStateException("No activity available!");
}

this.cameraName = cameraName;
this.enableAudio = enableAudio;
if (imageFormat != 256 || imageFormat != 35) {
this.imageFormat = 35;
} else {
this.imageFormat = imageFormat;
}
this.flutterTexture = flutterTexture;
this.dartMessenger = dartMessenger;
this.cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
Expand Down Expand Up @@ -148,7 +155,7 @@ public void open(@NonNull final Result result) throws CameraAccessException {
// Used to steam image byte data to dart side.
imageStreamReader =
ImageReader.newInstance(
previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);
previewSize.getWidth(), previewSize.getHeight(), this.imageFormat, 2);

cameraManager.openCamera(
cameraName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result)
case "startImageStream":
{
try {
call.arguments();
camera.startPreviewWithImageStream(imageStreamChannel);
result.success(null);
} catch (Exception e) {
Expand Down Expand Up @@ -145,6 +146,7 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce
String cameraName = call.argument("cameraName");
String resolutionPreset = call.argument("resolutionPreset");
boolean enableAudio = call.argument("enableAudio");
int androidFormatCode = call.argument("androidFormatCode");
TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture =
textureRegistry.createSurfaceTexture();
DartMessenger dartMessenger = new DartMessenger(messenger, flutterSurfaceTexture.id());
Expand All @@ -155,7 +157,8 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce
dartMessenger,
cameraName,
resolutionPreset,
enableAudio);
enableAudio,
androidFormatCode);

camera.open(result);
}
Expand Down
16 changes: 16 additions & 0 deletions packages/camera/lib/camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ class CameraController extends ValueNotifier<CameraValue> {
this.description,
this.resolutionPreset, {
this.enableAudio = true,
this.androidFormatCode = 35,
}) : super(const CameraValue.uninitialized());

final CameraDescription description;
Expand All @@ -253,6 +254,16 @@ class CameraController extends ValueNotifier<CameraValue> {
/// Whether to include audio when recording a video.
final bool enableAudio;

/// Define streaming image format for Android.
///
/// Default is `35` which is `YUV_420_888` on Android. See:
/// https://developer.android.com/reference/android/graphics/ImageFormat#YUV_420_888
///
/// Other option is `256` which is `JPEG`. When you specified the JPEG option,
/// [CameraImage] will have only one plane which is encoded JPEG bytes.
/// https://developer.android.com/reference/android/graphics/ImageFormat#JPEG
final int androidFormatCode;

int _textureId;
bool _isDisposed = false;
StreamSubscription<dynamic> _eventSubscription;
Expand All @@ -266,6 +277,10 @@ class CameraController extends ValueNotifier<CameraValue> {
if (_isDisposed) {
return Future<void>.value();
}
if (androidFormatCode != 256 && androidFormatCode != 35) {
throw CameraException('Unknown Image Format Code.',
'CameraController initialized with an unknown Image Format Code.');
}
try {
_creatingCompleter = Completer<void>();
final Map<String, dynamic> reply =
Expand All @@ -275,6 +290,7 @@ class CameraController extends ValueNotifier<CameraValue> {
'cameraName': description.name,
'resolutionPreset': serializeResolutionPreset(resolutionPreset),
'enableAudio': enableAudio,
'androidFormatCode': androidFormatCode,
},
);
_textureId = reply['textureId'];
Expand Down
14 changes: 12 additions & 2 deletions packages/camera/lib/camera_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ enum ImageFormatGroup {
///
/// On iOS, this is `kCVPixelFormatType_32BGRA`. See
/// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_32bgra?language=objc
///
bgra8888,

/// 32-big RGB image encoded into JPEG bytes.
///
/// On Android, this is `android.graphics.ImageFormat.JPEG`. See
/// https://developer.android.com/reference/android/graphics/ImageFormat#FLEX_RGBA_8888
OgulcanCelik marked this conversation as resolved.
Show resolved Hide resolved
///
jpeg
}

/// Describes how pixels are represented in an image.
Expand All @@ -84,8 +92,10 @@ class ImageFormat {
ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) {
if (defaultTargetPlatform == TargetPlatform.android) {
// android.graphics.ImageFormat.YUV_420_888
if (rawFormat == 35) {
return ImageFormatGroup.yuv420;
if (rawFormat == 256) {
return ImageFormatGroup.jpeg;
} else if (rawFormat == 42) {
return ImageFormatGroup.bgra8888;
OgulcanCelik marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/camera/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: camera
description: A Flutter plugin for getting information about and controlling the
camera on Android and iOS. Supports previewing the camera feed, capturing images, capturing video,
and streaming image buffers to dart.
version: 0.5.8+3
version: 0.5.8+4

homepage: https://github.com/flutter/plugins/tree/master/packages/camera

Expand Down