From 0a971a6fc4bec818599f84e55f2b574884edc222 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:26:14 +0100 Subject: [PATCH 01/45] Implemented ImageStream ImageFormat setting for Dart and Android --- .../io/flutter/plugins/camera/Camera.java | 11 ++-- .../plugins/camera/MethodCallHandlerImpl.java | 2 +- packages/camera/camera/example/lib/main.dart | 1 + packages/camera/camera/example/pubspec.yaml | 2 +- .../camera/lib/src/camera_controller.dart | 55 ++++++++++++------- .../camera/camera/lib/src/camera_image.dart | 45 ++++++++++++++- packages/camera/camera/pubspec.yaml | 5 +- packages/camera/camera/test/camera_test.dart | 18 ++++++ .../method_channel/method_channel_camera.dart | 4 +- .../platform_interface/camera_platform.dart | 2 +- 10 files changed, 112 insertions(+), 33 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 306dd447cfb9..514cef428931 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -138,15 +138,14 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { } @SuppressLint("MissingPermission") - public void open() throws CameraAccessException { + public void open(Integer imageStreamImageFormat) throws CameraAccessException { pictureImageReader = - ImageReader.newInstance( - captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); - + ImageReader.newInstance( + captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); // Used to steam image byte data to dart side. imageStreamReader = - ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2); + ImageReader.newInstance( + previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); cameraManager.openCamera( cameraName, diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 6c2e65e76f9e..51a5ea77cfad 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -78,7 +78,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) { if (camera != null) { try { - camera.open(); + camera.open(call.argument("imageStreamImageFormat")); result.success(null); } catch (Exception e) { handleException(e, result); diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index e1edc1b06386..a323961fa72d 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -283,6 +283,7 @@ class _CameraExampleHomeState extends State cameraDescription, ResolutionPreset.medium, enableAudio: enableAudio, + imageStreamImageFormat: ImageFormatGroup.jpeg ); // If the controller is updated then update the UI. diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 0d1f03bef437..c1e6b8fa3319 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -22,5 +22,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index fcf00245ce7f..c4cb43e77ceb 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -36,6 +36,7 @@ class CameraValue { this.isTakingPicture, this.isStreamingImages, bool isRecordingPaused, + this.imageStreamImageFormat, }) : _isRecordingPaused = isRecordingPaused; /// Creates a new camera controller state for an uninitialized controller. @@ -86,28 +87,33 @@ class CameraValue { /// When true [errorDescription] describes the error. bool get hasError => errorDescription != null; + /// The [ImageFormatGroup] describes the output of the raw image format. + /// + /// When null the imageFormat will fallback to the platforms default + final ImageFormatGroup imageStreamImageFormat; + /// Creates a modified copy of the object. /// /// Explicitly specified fields get the specified value, all other fields get /// the same value of the current object. - CameraValue copyWith({ - bool isInitialized, - bool isRecordingVideo, - bool isTakingPicture, - bool isStreamingImages, - String errorDescription, - Size previewSize, - bool isRecordingPaused, - }) { + CameraValue copyWith( + {bool isInitialized, + bool isRecordingVideo, + bool isTakingPicture, + bool isStreamingImages, + String errorDescription, + Size previewSize, + bool isRecordingPaused, + ImageFormatGroup imageStreamImageFormat}) { return CameraValue( - isInitialized: isInitialized ?? this.isInitialized, - errorDescription: errorDescription, - previewSize: previewSize ?? this.previewSize, - isRecordingVideo: isRecordingVideo ?? this.isRecordingVideo, - isTakingPicture: isTakingPicture ?? this.isTakingPicture, - isStreamingImages: isStreamingImages ?? this.isStreamingImages, - isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, - ); + isInitialized: isInitialized ?? this.isInitialized, + errorDescription: errorDescription, + previewSize: previewSize ?? this.previewSize, + isRecordingVideo: isRecordingVideo ?? this.isRecordingVideo, + isTakingPicture: isTakingPicture ?? this.isTakingPicture, + isStreamingImages: isStreamingImages ?? this.isStreamingImages, + isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, + imageStreamImageFormat: imageStreamImageFormat ?? this.imageStreamImageFormat); } @override @@ -117,7 +123,8 @@ class CameraValue { 'isInitialized: $isInitialized, ' 'errorDescription: $errorDescription, ' 'previewSize: $previewSize, ' - 'isStreamingImages: $isStreamingImages)'; + 'isStreamingImages: $isStreamingImages, ' + 'imageStreamImageFormat: $imageStreamImageFormat)'; } } @@ -134,6 +141,7 @@ class CameraController extends ValueNotifier { this.description, this.resolutionPreset, { this.enableAudio = true, + this.imageStreamImageFormat, }) : super(const CameraValue.uninitialized()); /// The properties of the camera device controlled by this controller. @@ -150,6 +158,11 @@ class CameraController extends ValueNotifier { /// Whether to include audio when recording a video. final bool enableAudio; + /// The [ImageFormatGroup] describes the output of the raw image format. + /// + /// When null the imageFormat will fallback to the platforms default + final ImageFormatGroup imageStreamImageFormat; + int _cameraId; bool _isDisposed = false; StreamSubscription _imageStreamSubscription; @@ -190,11 +203,15 @@ class CameraController extends ValueNotifier { ); }).first; - await CameraPlatform.instance.initializeCamera(_cameraId); + await CameraPlatform.instance.initializeCamera( + _cameraId, + imageStreamImageFormat: imageFormatGroupAsIntegerValue(imageStreamImageFormat), + ); value = value.copyWith( isInitialized: true, previewSize: await previewSize, + imageStreamImageFormat: imageStreamImageFormat ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index ca8115eb758d..22a4d7d905c4 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -65,6 +65,12 @@ 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#JPEG + jpeg, } /// Describes how pixels are represented in an image. @@ -86,9 +92,13 @@ class ImageFormat { ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) { if (defaultTargetPlatform == TargetPlatform.android) { + switch (rawFormat) { // android.graphics.ImageFormat.YUV_420_888 - if (rawFormat == 35) { - return ImageFormatGroup.yuv420; + case 35: + return ImageFormatGroup.yuv420; + // android.graphics.ImageFormat.JPEG + case 256: + return ImageFormatGroup.jpeg; } } @@ -106,6 +116,37 @@ ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) { return ImageFormatGroup.unknown; } +/// Converts [ImageFormatGroup] to integer definition of the raw format +int imageFormatGroupAsIntegerValue(ImageFormatGroup imageFormatGroup) { + if (defaultTargetPlatform == TargetPlatform.iOS) { + switch (imageFormatGroup) { + // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange + case ImageFormatGroup.yuv420: + return 875704438; + // kCVPixelFormatType_32BGRA + case ImageFormatGroup.bgra8888: + return 1111970369; + case ImageFormatGroup.jpeg: + case ImageFormatGroup.unknown: + return 0; + } + } else if (defaultTargetPlatform == TargetPlatform.android) { + switch (imageFormatGroup) { + // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange + case ImageFormatGroup.yuv420: + return 35; + // kCVPixelFormatType_32BGRA + case ImageFormatGroup.bgra8888: + case ImageFormatGroup.unknown: + return 0; + case ImageFormatGroup.jpeg: + return 256; + } + } + // unknown ImageFormatGroup or unsupported platform + return 0; +} + /// A single complete image buffer from the platform camera. /// /// This class allows for direct application access to the pixel data of an diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index cc25133f95f9..bb8665ecc6d2 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -8,7 +8,8 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.0.0 + camera_platform_interface: + path: ../camera_platform_interface dev_dependencies: path_provider: ^0.5.0 @@ -31,5 +32,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.6.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index b129849cd141..e3171996b2e8 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -311,6 +311,24 @@ void main() { ))); }); }); + + test('imageFormat can be set', () async { + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max, + imageStreamImageFormat: ImageFormatGroup.jpeg, + ); + + await cameraController.initialize(); + expect(cameraController.value.imageStreamImageFormat, ImageFormatGroup.jpeg); + }); + + // test('imageFormat throws $CameraException when uninitialized', () { + // //TODO + // }); } class MockCameraPlatform extends Mock diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 3bf996fedb19..f0d1a99c8d70 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:cross_file/cross_file.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; @@ -75,7 +76,7 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId) { + Future initializeCamera(int cameraId, {int imageStreamImageFormat}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -93,6 +94,7 @@ class MethodChannelCamera extends CameraPlatform { 'initialize', { 'cameraId': cameraId, + 'imageStreamImageFormat': imageStreamImageFormat, }, ); diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 6f96079dc55c..1958bb48e495 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -52,7 +52,7 @@ abstract class CameraPlatform extends PlatformInterface { } /// Initializes the camera on the device. - Future initializeCamera(int cameraId) { + Future initializeCamera(int cameraId, {int imageStreamImageFormat}) { throw UnimplementedError('initializeCamera() is not implemented.'); } From 9773fea1d2bb0ee59f625c9740ed291309dfd307 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:32:27 +0100 Subject: [PATCH 02/45] Fixed formatting and toString test --- .../camera/lib/src/camera_controller.dart | 47 ++++++++++--------- .../camera/camera/test/camera_value_test.dart | 2 +- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index c4cb43e77ceb..a47045aef0e0 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -96,24 +96,27 @@ class CameraValue { /// /// Explicitly specified fields get the specified value, all other fields get /// the same value of the current object. - CameraValue copyWith( - {bool isInitialized, - bool isRecordingVideo, - bool isTakingPicture, - bool isStreamingImages, - String errorDescription, - Size previewSize, - bool isRecordingPaused, - ImageFormatGroup imageStreamImageFormat}) { + CameraValue copyWith({ + bool isInitialized, + bool isRecordingVideo, + bool isTakingPicture, + bool isStreamingImages, + String errorDescription, + Size previewSize, + bool isRecordingPaused, + ImageFormatGroup imageStreamImageFormat, + }) { return CameraValue( - isInitialized: isInitialized ?? this.isInitialized, - errorDescription: errorDescription, - previewSize: previewSize ?? this.previewSize, - isRecordingVideo: isRecordingVideo ?? this.isRecordingVideo, - isTakingPicture: isTakingPicture ?? this.isTakingPicture, - isStreamingImages: isStreamingImages ?? this.isStreamingImages, - isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, - imageStreamImageFormat: imageStreamImageFormat ?? this.imageStreamImageFormat); + isInitialized: isInitialized ?? this.isInitialized, + errorDescription: errorDescription, + previewSize: previewSize ?? this.previewSize, + isRecordingVideo: isRecordingVideo ?? this.isRecordingVideo, + isTakingPicture: isTakingPicture ?? this.isTakingPicture, + isStreamingImages: isStreamingImages ?? this.isStreamingImages, + isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, + imageStreamImageFormat: + imageStreamImageFormat ?? this.imageStreamImageFormat, + ); } @override @@ -205,14 +208,14 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.initializeCamera( _cameraId, - imageStreamImageFormat: imageFormatGroupAsIntegerValue(imageStreamImageFormat), + imageStreamImageFormat: + imageFormatGroupAsIntegerValue(imageStreamImageFormat), ); value = value.copyWith( - isInitialized: true, - previewSize: await previewSize, - imageStreamImageFormat: imageStreamImageFormat - ); + isInitialized: true, + previewSize: await previewSize, + imageStreamImageFormat: imageStreamImageFormat); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index 28255eb0a568..de6a1cac524b 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -96,7 +96,7 @@ void main() { ); expect(cameraValue.toString(), - 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false)'); + 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, imageStreamImageFormat: null)'); }); }); } From db6c88a5e73f095201b50a19613ded6a469a3cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Mon, 21 Dec 2020 13:35:46 +0100 Subject: [PATCH 03/45] Apply suggestions from code review --- packages/camera/camera/example/pubspec.yaml | 2 +- packages/camera/camera/pubspec.yaml | 2 +- packages/camera/camera/test/camera_test.dart | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index c1e6b8fa3319..0d1f03bef437 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -22,5 +22,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.6.0 <3.0.0" + sdk: ">=2.0.0-dev.28.0 <3.0.0" flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index bb8665ecc6d2..6ddf4e5a532f 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -32,5 +32,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: ">=2.6.0 <3.0.0" + sdk: ">=2.1.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index e3171996b2e8..aee0f2ea92b0 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -326,9 +326,6 @@ void main() { expect(cameraController.value.imageStreamImageFormat, ImageFormatGroup.jpeg); }); - // test('imageFormat throws $CameraException when uninitialized', () { - // //TODO - // }); } class MockCameraPlatform extends Mock From fa714939bfd415817d5d0c2493647526616cc2cd Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:39:02 +0100 Subject: [PATCH 04/45] Removed imageStreamImageFormat from CameraValue --- packages/camera/camera/lib/src/camera_controller.dart | 11 +---------- packages/camera/camera/test/camera_value_test.dart | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index a47045aef0e0..2ab2a683a5aa 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -36,7 +36,6 @@ class CameraValue { this.isTakingPicture, this.isStreamingImages, bool isRecordingPaused, - this.imageStreamImageFormat, }) : _isRecordingPaused = isRecordingPaused; /// Creates a new camera controller state for an uninitialized controller. @@ -87,11 +86,6 @@ class CameraValue { /// When true [errorDescription] describes the error. bool get hasError => errorDescription != null; - /// The [ImageFormatGroup] describes the output of the raw image format. - /// - /// When null the imageFormat will fallback to the platforms default - final ImageFormatGroup imageStreamImageFormat; - /// Creates a modified copy of the object. /// /// Explicitly specified fields get the specified value, all other fields get @@ -114,8 +108,6 @@ class CameraValue { isTakingPicture: isTakingPicture ?? this.isTakingPicture, isStreamingImages: isStreamingImages ?? this.isStreamingImages, isRecordingPaused: isRecordingPaused ?? _isRecordingPaused, - imageStreamImageFormat: - imageStreamImageFormat ?? this.imageStreamImageFormat, ); } @@ -126,8 +118,7 @@ class CameraValue { 'isInitialized: $isInitialized, ' 'errorDescription: $errorDescription, ' 'previewSize: $previewSize, ' - 'isStreamingImages: $isStreamingImages, ' - 'imageStreamImageFormat: $imageStreamImageFormat)'; + 'isStreamingImages: $isStreamingImages)'; } } diff --git a/packages/camera/camera/test/camera_value_test.dart b/packages/camera/camera/test/camera_value_test.dart index de6a1cac524b..28255eb0a568 100644 --- a/packages/camera/camera/test/camera_value_test.dart +++ b/packages/camera/camera/test/camera_value_test.dart @@ -96,7 +96,7 @@ void main() { ); expect(cameraValue.toString(), - 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false, imageStreamImageFormat: null)'); + 'CameraValue(isRecordingVideo: false, isInitialized: false, errorDescription: null, previewSize: Size(10.0, 10.0), isStreamingImages: false)'); }); }); } From e94b474030fd93dac40cda1c8c33c6f54b81f144 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:39:52 +0100 Subject: [PATCH 05/45] Removed imageStreamImageFormat from CameraValue --- packages/camera/camera/test/camera_test.dart | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index aee0f2ea92b0..b129849cd141 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -311,21 +311,6 @@ void main() { ))); }); }); - - test('imageFormat can be set', () async { - CameraController cameraController = CameraController( - CameraDescription( - name: 'cam', - lensDirection: CameraLensDirection.back, - sensorOrientation: 90), - ResolutionPreset.max, - imageStreamImageFormat: ImageFormatGroup.jpeg, - ); - - await cameraController.initialize(); - expect(cameraController.value.imageStreamImageFormat, ImageFormatGroup.jpeg); - }); - } class MockCameraPlatform extends Mock From ccd02254bc06746c1c92001f4f04d0ec2bcf91ed Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:41:25 +0100 Subject: [PATCH 06/45] Removed imageStreamImageFormat from CameraValue --- packages/camera/camera/lib/src/camera_controller.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 2ab2a683a5aa..c2fa724f8fad 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -98,7 +98,6 @@ class CameraValue { String errorDescription, Size previewSize, bool isRecordingPaused, - ImageFormatGroup imageStreamImageFormat, }) { return CameraValue( isInitialized: isInitialized ?? this.isInitialized, @@ -204,9 +203,9 @@ class CameraController extends ValueNotifier { ); value = value.copyWith( - isInitialized: true, - previewSize: await previewSize, - imageStreamImageFormat: imageStreamImageFormat); + isInitialized: true, + previewSize: await previewSize, + ); } on PlatformException catch (e) { throw CameraException(e.code, e.message); } From fa0c68576921cad30d4b63ca6c1d81a3441e4bec Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:43:10 +0100 Subject: [PATCH 07/45] fixed formatting --- .../android/src/main/java/io/flutter/plugins/camera/Camera.java | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 514cef428931..81a0a84f8f61 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -142,6 +142,7 @@ public void open(Integer imageStreamImageFormat) throws CameraAccessException { pictureImageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); + // Used to steam image byte data to dart side. imageStreamReader = ImageReader.newInstance( From 39bd9d1b312a4e9773be7430a60731ee99146215 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:43:57 +0100 Subject: [PATCH 08/45] fixed formatting --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 81a0a84f8f61..ae1377e00cf0 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -140,13 +140,13 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { @SuppressLint("MissingPermission") public void open(Integer imageStreamImageFormat) throws CameraAccessException { pictureImageReader = - ImageReader.newInstance( - captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); + ImageReader.newInstance( + captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); // Used to steam image byte data to dart side. imageStreamReader = - ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); + ImageReader.newInstance( + previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); cameraManager.openCamera( cameraName, From 288684f01674bbb2dd86d796d993435d5f8404a9 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:44:30 +0100 Subject: [PATCH 09/45] fixed formatting --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index ae1377e00cf0..c28ed6a846b6 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -141,12 +141,12 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { public void open(Integer imageStreamImageFormat) throws CameraAccessException { pictureImageReader = ImageReader.newInstance( - captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); + captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); // Used to steam image byte data to dart side. imageStreamReader = ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); + previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); cameraManager.openCamera( cameraName, From b1ddd577b14f04b703bc3b4a80e88a6f5c4a1d20 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 21 Dec 2020 13:56:09 +0100 Subject: [PATCH 10/45] WIP: iOS implementation --- packages/camera/camera/ios/Classes/CameraPlugin.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 9455375b8524..147cdd3cf1c0 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -193,7 +193,7 @@ @implementation FLTCam { dispatch_queue_t _dispatchQueue; } // Format used for video and image streaming. -FourCharCode const videoFormat = kCVPixelFormatType_32BGRA; +FourCharCode videoFormat = kCVPixelFormatType_32BGRA; NSString *const errorMethod = @"error"; - (instancetype)initWithCameraName:(NSString *)cameraName @@ -872,6 +872,8 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSDictionary *argsMap = call.arguments; NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { + // TODO: Set actual videoFormat? Or is it possible to set an integer + videoFormat = ((NSNumber *)argsMap[@"imageStreamImageFormat"]).unsignedIntegerValue; __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; From 332c2ba1d4afa35aab79b3cb0329a9b3bb442925 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Tue, 22 Dec 2020 12:32:58 +0100 Subject: [PATCH 11/45] Imaplemented suggested changes, added tests. --- .../io/flutter/plugins/camera/Camera.java | 6 ++- .../plugins/camera/MethodCallHandlerImpl.java | 2 +- packages/camera/camera/example/lib/main.dart | 2 +- .../camera/camera/ios/Classes/CameraPlugin.m | 2 +- .../camera/lib/src/camera_controller.dart | 9 +++-- .../camera/camera/lib/src/camera_image.dart | 31 --------------- .../camera/lib/utils/image_format_utils.dart | 34 ++++++++++++++++ packages/camera/camera/test/camera_test.dart | 39 +++++++++++++++++++ .../method_channel/method_channel_camera.dart | 4 +- .../platform_interface/camera_platform.dart | 6 ++- .../method_channel_camera_test.dart | 11 +++++- 11 files changed, 101 insertions(+), 45 deletions(-) create mode 100644 packages/camera/camera/lib/utils/image_format_utils.dart diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index c28ed6a846b6..edc9316e5d83 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -138,15 +138,17 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { } @SuppressLint("MissingPermission") - public void open(Integer imageStreamImageFormat) throws CameraAccessException { + public void open(Integer imageFormatGroup) throws CameraAccessException { pictureImageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); + imageFormatGroup = imageFormatGroup != null? imageFormatGroup : ImageFormat.YUV_420_888; + // Used to steam image byte data to dart side. imageStreamReader = ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), imageStreamImageFormat != null? imageStreamImageFormat : ImageFormat.YUV_420_888, 2); + previewSize.getWidth(), previewSize.getHeight(), imageFormatGroup, 2); cameraManager.openCamera( cameraName, diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 51a5ea77cfad..1e0cd9bd64c7 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -78,7 +78,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) { if (camera != null) { try { - camera.open(call.argument("imageStreamImageFormat")); + camera.open(call.argument("imageFormatGroup")); result.success(null); } catch (Exception e) { handleException(e, result); diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index a323961fa72d..e86417345afe 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -283,7 +283,7 @@ class _CameraExampleHomeState extends State cameraDescription, ResolutionPreset.medium, enableAudio: enableAudio, - imageStreamImageFormat: ImageFormatGroup.jpeg + imageFormatGroup: ImageFormatGroup.jpeg ); // If the controller is updated then update the UI. diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 147cdd3cf1c0..65b1a1f48f9b 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -873,7 +873,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { // TODO: Set actual videoFormat? Or is it possible to set an integer - videoFormat = ((NSNumber *)argsMap[@"imageStreamImageFormat"]).unsignedIntegerValue; + videoFormat = ((NSNumber *)argsMap[@"imageFormatGroup"]).unsignedIntegerValue; __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index c2fa724f8fad..418d85777c2d 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -10,6 +10,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import '../utils/image_format_utils.dart'; + final MethodChannel _channel = const MethodChannel('plugins.flutter.io/camera'); /// Signature for a callback receiving the a camera image. @@ -134,7 +136,7 @@ class CameraController extends ValueNotifier { this.description, this.resolutionPreset, { this.enableAudio = true, - this.imageStreamImageFormat, + this.imageFormatGroup, }) : super(const CameraValue.uninitialized()); /// The properties of the camera device controlled by this controller. @@ -154,7 +156,7 @@ class CameraController extends ValueNotifier { /// The [ImageFormatGroup] describes the output of the raw image format. /// /// When null the imageFormat will fallback to the platforms default - final ImageFormatGroup imageStreamImageFormat; + final ImageFormatGroup imageFormatGroup; int _cameraId; bool _isDisposed = false; @@ -198,8 +200,7 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.initializeCamera( _cameraId, - imageStreamImageFormat: - imageFormatGroupAsIntegerValue(imageStreamImageFormat), + imageFormatGroup: imageFormatGroupAsIntegerValue(imageFormatGroup), ); value = value.copyWith( diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index 22a4d7d905c4..36c8983e8f56 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -116,37 +116,6 @@ ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) { return ImageFormatGroup.unknown; } -/// Converts [ImageFormatGroup] to integer definition of the raw format -int imageFormatGroupAsIntegerValue(ImageFormatGroup imageFormatGroup) { - if (defaultTargetPlatform == TargetPlatform.iOS) { - switch (imageFormatGroup) { - // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange - case ImageFormatGroup.yuv420: - return 875704438; - // kCVPixelFormatType_32BGRA - case ImageFormatGroup.bgra8888: - return 1111970369; - case ImageFormatGroup.jpeg: - case ImageFormatGroup.unknown: - return 0; - } - } else if (defaultTargetPlatform == TargetPlatform.android) { - switch (imageFormatGroup) { - // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange - case ImageFormatGroup.yuv420: - return 35; - // kCVPixelFormatType_32BGRA - case ImageFormatGroup.bgra8888: - case ImageFormatGroup.unknown: - return 0; - case ImageFormatGroup.jpeg: - return 256; - } - } - // unknown ImageFormatGroup or unsupported platform - return 0; -} - /// A single complete image buffer from the platform camera. /// /// This class allows for direct application access to the pixel data of an diff --git a/packages/camera/camera/lib/utils/image_format_utils.dart b/packages/camera/camera/lib/utils/image_format_utils.dart new file mode 100644 index 000000000000..9e62b1d45b94 --- /dev/null +++ b/packages/camera/camera/lib/utils/image_format_utils.dart @@ -0,0 +1,34 @@ +import 'package:flutter/foundation.dart'; + +import '../camera.dart'; + +/// Converts [ImageFormatGroup] to integer definition of the raw format +int imageFormatGroupAsIntegerValue(ImageFormatGroup imageFormatGroup) { + if (defaultTargetPlatform == TargetPlatform.iOS) { + switch (imageFormatGroup) { + // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange + case ImageFormatGroup.yuv420: + return 875704438; + // kCVPixelFormatType_32BGRA + case ImageFormatGroup.bgra8888: + return 1111970369; + case ImageFormatGroup.jpeg: + case ImageFormatGroup.unknown: + return 0; + } + } else if (defaultTargetPlatform == TargetPlatform.android) { + switch (imageFormatGroup) { + // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange + case ImageFormatGroup.yuv420: + return 35; + // kCVPixelFormatType_32BGRA + case ImageFormatGroup.bgra8888: + case ImageFormatGroup.unknown: + return 0; + case ImageFormatGroup.jpeg: + return 256; + } + } + // unknown ImageFormatGroup or unsupported platform + return 0; +} \ No newline at end of file diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index b129849cd141..91740abda501 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -6,7 +6,9 @@ import 'dart:async'; import 'dart:ui'; import 'package:camera/camera.dart'; +import 'package:camera/utils/image_format_utils.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -83,6 +85,11 @@ void main() { CameraPlatform.instance = MockCameraPlatform(); }); + tearDown(() { + (CameraPlatform.instance as MockCameraPlatform).log.clear(); + }); + + test('Can be initialized', () async { CameraController cameraController = CameraController( CameraDescription( @@ -162,6 +169,26 @@ void main() { mockPlatformException = false; }); + test('initialize() sets imageFormat', () async { + + debugDefaultTargetPlatformOverride = TargetPlatform.android; + CameraController cameraController = CameraController( + CameraDescription( + name: 'cam', + lensDirection: CameraLensDirection.back, + sensorOrientation: 90), + ResolutionPreset.max, + imageFormatGroup: ImageFormatGroup.yuv420, + ); + await cameraController.initialize(); + + expect((CameraPlatform.instance as MockCameraPlatform).log.first, { + 'method': 'initializeCamera', + 'cameraId': 13, + 'imageFormatGroup': imageFormatGroupAsIntegerValue(ImageFormatGroup.yuv420), + }); + }); + test('prepareForVideoRecording() calls $CameraPlatform ', () async { CameraController cameraController = CameraController( CameraDescription( @@ -316,6 +343,18 @@ void main() { class MockCameraPlatform extends Mock with MockPlatformInterfaceMixin implements CameraPlatform { + final log = []; + + @override + Future initializeCamera(int cameraId, {int imageFormatGroup}) { + log.add({ + 'method': 'initializeCamera', + 'cameraId': cameraId, + 'imageFormatGroup': imageFormatGroup, + }); + return null; + } + @override Future> availableCameras() => Future.value(mockAvailableCameras); diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index f0d1a99c8d70..a26afed425d5 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -76,7 +76,7 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId, {int imageStreamImageFormat}) { + Future initializeCamera(int cameraId, {int imageFormatGroup}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -94,7 +94,7 @@ class MethodChannelCamera extends CameraPlatform { 'initialize', { 'cameraId': cameraId, - 'imageStreamImageFormat': imageStreamImageFormat, + 'imageFormatGroup': imageFormatGroup, }, ); diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 1958bb48e495..a3fd61d401e7 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -52,7 +52,11 @@ abstract class CameraPlatform extends PlatformInterface { } /// Initializes the camera on the device. - Future initializeCamera(int cameraId, {int imageStreamImageFormat}) { + /// + /// [imageFormatGroup] is used to specify the image formatting used. + /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. + /// On iOS this defaults to kCVPixelFormatType_32BGRA + Future initializeCamera(int cameraId, {int imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index c461b1fd583c..bb24ea7cae2f 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -24,7 +24,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1} + 'create': { + 'cameraId': 1, + 'imageFormatGroup': null, + } }); final camera = MethodChannelCamera(); @@ -107,7 +110,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1}, + 'create': { + 'cameraId': 1, + 'imageFormatGroup': null, + }, 'initialize': null }); final camera = MethodChannelCamera(); @@ -130,6 +136,7 @@ void main() { 'initialize', arguments: { 'cameraId': 1, + 'imageFormatGroup': null, }, ), ]); From 9188fabb0f850e320317f4cb11ef68f943536138 Mon Sep 17 00:00:00 2001 From: anniek Date: Tue, 22 Dec 2020 13:46:24 +0100 Subject: [PATCH 12/45] iOS switch case videoFormat --- packages/camera/camera/ios/Classes/CameraPlugin.m | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 65b1a1f48f9b..f76aa2765cab 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -872,8 +872,18 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSDictionary *argsMap = call.arguments; NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { - // TODO: Set actual videoFormat? Or is it possible to set an integer - videoFormat = ((NSNumber *)argsMap[@"imageFormatGroup"]).unsignedIntegerValue; + int videoFormatValue = ((NSNumber *)argsMap[@"imageFormatGroup"]).unsignedIntegerValue; + switch (videoFormatValue) { + case 1111970369: + videoFormat = kCVPixelFormatType_32BGRA; + break; + case 875704438: + videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + break; + default: + videoFormat = kCVPixelFormatType_32BGRA; + + } __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; From a9ca8295abdac6e70a36aa0b7144dbefa13e15d0 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Tue, 22 Dec 2020 14:03:55 +0100 Subject: [PATCH 13/45] Added imageFormatGroup to initialize --- .../camera/camera_platform_interface/CHANGELOG.md | 4 ++++ .../lib/src/method_channel/method_channel_camera.dart | 3 ++- .../lib/src/platform_interface/camera_platform.dart | 6 +++++- .../camera/camera_platform_interface/pubspec.yaml | 2 +- .../method_channel/method_channel_camera_test.dart | 11 +++++++++-- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index ea9821e841f9..efb1733697be 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +- Introduces option to set ImageFormat when initializing + ## 1.0.4 - Added the torch option to the FlashMode enum, which when implemented indicates the flash light should be turned on continuously. diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 3bf996fedb19..f79b25e4aa32 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -75,7 +75,7 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId) { + Future initializeCamera(int cameraId, {int imageFormatGroup}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -93,6 +93,7 @@ class MethodChannelCamera extends CameraPlatform { 'initialize', { 'cameraId': cameraId, + 'imageFormatGroup': imageFormatGroup, }, ); diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 6f96079dc55c..a3fd61d401e7 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -52,7 +52,11 @@ abstract class CameraPlatform extends PlatformInterface { } /// Initializes the camera on the device. - Future initializeCamera(int cameraId) { + /// + /// [imageFormatGroup] is used to specify the image formatting used. + /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. + /// On iOS this defaults to kCVPixelFormatType_32BGRA + Future initializeCamera(int cameraId, {int imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index 8cb643e84ca6..b6933314d41d 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.4 +version: 1.1.0 dependencies: flutter: diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index c461b1fd583c..bb24ea7cae2f 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -24,7 +24,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1} + 'create': { + 'cameraId': 1, + 'imageFormatGroup': null, + } }); final camera = MethodChannelCamera(); @@ -107,7 +110,10 @@ void main() { MethodChannelMock cameraMockChannel = MethodChannelMock( channelName: 'plugins.flutter.io/camera', methods: { - 'create': {'cameraId': 1}, + 'create': { + 'cameraId': 1, + 'imageFormatGroup': null, + }, 'initialize': null }); final camera = MethodChannelCamera(); @@ -130,6 +136,7 @@ void main() { 'initialize', arguments: { 'cameraId': 1, + 'imageFormatGroup': null, }, ), ]); From ec6aa454ddaa3ece25a54205f909b672ed49a6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Tue, 22 Dec 2020 15:15:57 +0100 Subject: [PATCH 14/45] Apply suggestions from code review Co-authored-by: Maurits van Beusekom --- packages/camera/camera_platform_interface/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md index efb1733697be..add01384e967 100644 --- a/packages/camera/camera_platform_interface/CHANGELOG.md +++ b/packages/camera/camera_platform_interface/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.1.0 -- Introduces option to set ImageFormat when initializing +- Introduces an option to set the image format when initializing. ## 1.0.4 From 56f77eccb558b37a2ac976fe7c26af0c473a38d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl?= <32639467+danielroek@users.noreply.github.com> Date: Tue, 22 Dec 2020 15:16:43 +0100 Subject: [PATCH 15/45] Added period to sentence --- .../lib/src/platform_interface/camera_platform.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index a3fd61d401e7..ce57d9ce03cf 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -55,7 +55,7 @@ abstract class CameraPlatform extends PlatformInterface { /// /// [imageFormatGroup] is used to specify the image formatting used. /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. - /// On iOS this defaults to kCVPixelFormatType_32BGRA + /// On iOS this defaults to kCVPixelFormatType_32BGRA. Future initializeCamera(int cameraId, {int imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } From ecea347a6cefe292759ddc48162034f56e250002 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 13:48:36 +0100 Subject: [PATCH 16/45] Moved ImageFormatGroup to platform_interface; Added extension to convert ImageFormatGroup to name; Changed int to ImageFormatGroup for initializeCamera --- .../method_channel/method_channel_camera.dart | 5 +- .../platform_interface/camera_platform.dart | 3 +- .../lib/src/types/image_format_group.dart | 51 +++++++++++++++++++ .../camera_platform_interface/pubspec.yaml | 2 +- 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index f79b25e4aa32..8a8bb5339b85 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:camera_platform_interface/camera_platform_interface.dart'; +import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:camera_platform_interface/src/utils/utils.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/services.dart'; @@ -75,7 +76,7 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId, {int imageFormatGroup}) { + Future initializeCamera(int cameraId, {ImageFormatGroup imageFormatGroup}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( @@ -93,7 +94,7 @@ class MethodChannelCamera extends CameraPlatform { 'initialize', { 'cameraId': cameraId, - 'imageFormatGroup': imageFormatGroup, + 'imageFormatGroup': imageFormatGroup.name(), }, ); diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index ce57d9ce03cf..6ec977047902 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart'; +import 'package:camera_platform_interface/src/types/image_format_group.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/widgets.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -56,7 +57,7 @@ abstract class CameraPlatform extends PlatformInterface { /// [imageFormatGroup] is used to specify the image formatting used. /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. /// On iOS this defaults to kCVPixelFormatType_32BGRA. - Future initializeCamera(int cameraId, {int imageFormatGroup}) { + Future initializeCamera(int cameraId, {ImageFormatGroup imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart new file mode 100644 index 000000000000..48a0fa0be834 --- /dev/null +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -0,0 +1,51 @@ +// TODO:(bmparr) Turn [ImageFormatGroup] to a class with int values. + +/// Group of image formats that are comparable across Android and iOS platforms. +enum ImageFormatGroup { + /// The image format does not fit into any specific group. + unknown, + + /// Multi-plane YUV 420 format. + /// + /// This format is a generic YCbCr format, capable of describing any 4:2:0 + /// chroma-subsampled planar or semiplanar buffer (but not fully interleaved), + /// with 8 bits per color sample. + /// + /// On Android, this is `android.graphics.ImageFormat.YUV_420_888`. See + /// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888 + /// + /// On iOS, this is `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`. See + /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_420ypcbcr8biplanarvideorange?language=objc + yuv420, + + /// 32-bit BGRA. + /// + /// 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#JPEG + jpeg, +} + +/// Extension on [ImageFormatGroup] to stringify the enum +extension ImageFormatGroupName on ImageFormatGroup { + /// returns a String value for [ImageFormatGroup] + String name() { + switch (this) { + case ImageFormatGroup.jpeg: + return 'JPEG'; + case ImageFormatGroup.yuv420: + return 'YUV420'; + case ImageFormatGroup.bgra8888: + return 'BGRA888'; + case ImageFormatGroup.unknown: + return 'UNKNOWN'; + default: + return 'UNKNOWN'; + } + } +} diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml index b6933314d41d..0821fd39b5c1 100644 --- a/packages/camera/camera_platform_interface/pubspec.yaml +++ b/packages/camera/camera_platform_interface/pubspec.yaml @@ -21,5 +21,5 @@ dev_dependencies: pedantic: ^1.8.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.22.0" From ac23632ce3f0b01c7f19bafdeb2e23b6b3c5ad84 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 13:50:19 +0100 Subject: [PATCH 17/45] Fixed test --- .../test/method_channel/method_channel_camera_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index bb24ea7cae2f..3763da4df8da 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -26,7 +26,7 @@ void main() { methods: { 'create': { 'cameraId': 1, - 'imageFormatGroup': null, + 'imageFormatGroup': 'UNKNOWN', } }); final camera = MethodChannelCamera(); @@ -112,7 +112,7 @@ void main() { methods: { 'create': { 'cameraId': 1, - 'imageFormatGroup': null, + 'imageFormatGroup': 'UNKNOWN', }, 'initialize': null }); @@ -136,7 +136,7 @@ void main() { 'initialize', arguments: { 'cameraId': 1, - 'imageFormatGroup': null, + 'imageFormatGroup': 'UNKNOWN', }, ), ]); From 4eea926c6beeffd32e716ef202d3b35feabc7115 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 13:58:42 +0100 Subject: [PATCH 18/45] Separated Android and iOS in name extension --- .../lib/src/types/image_format_group.dart | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 48a0fa0be834..b6f9e2b0e3c5 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -1,4 +1,4 @@ -// TODO:(bmparr) Turn [ImageFormatGroup] to a class with int values. +import 'package:flutter/foundation.dart'; /// Group of image formats that are comparable across Android and iOS platforms. enum ImageFormatGroup { @@ -35,17 +35,30 @@ enum ImageFormatGroup { extension ImageFormatGroupName on ImageFormatGroup { /// returns a String value for [ImageFormatGroup] String name() { - switch (this) { - case ImageFormatGroup.jpeg: - return 'JPEG'; - case ImageFormatGroup.yuv420: - return 'YUV420'; - case ImageFormatGroup.bgra8888: - return 'BGRA888'; - case ImageFormatGroup.unknown: - return 'UNKNOWN'; - default: - return 'UNKNOWN'; + if (defaultTargetPlatform == TargetPlatform.android) { + switch (this) { + case ImageFormatGroup.jpeg: + return 'JPEG'; + case ImageFormatGroup.yuv420: + return 'YUV420'; + case ImageFormatGroup.bgra8888: + case ImageFormatGroup.unknown: + default: + return 'UNKNOWN'; + } + } else if (defaultTargetPlatform == TargetPlatform.iOS) { + switch (this) { + case ImageFormatGroup.bgra8888: + return 'BGRA888'; + case ImageFormatGroup.yuv420: + return 'YUV420'; + case ImageFormatGroup.jpeg: + case ImageFormatGroup.unknown: + default: + return 'UNKNOWN'; + } } + // unsupported platform + return 'UNKNOWN'; } } From 9a86d26f32627f46f29799850e344c716d6d6d2d Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:00:37 +0100 Subject: [PATCH 19/45] Clarified returns on name extension --- .../lib/src/types/image_format_group.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index b6f9e2b0e3c5..06bd111bc6d2 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -34,6 +34,8 @@ enum ImageFormatGroup { /// Extension on [ImageFormatGroup] to stringify the enum extension ImageFormatGroupName on ImageFormatGroup { /// returns a String value for [ImageFormatGroup] + /// returns 'UNKNOWN' if platform is not supported + /// or if [ImageFormatGroup] is not supported for the platform String name() { if (defaultTargetPlatform == TargetPlatform.android) { switch (this) { From f4e152fc9fb428fed9dfd8c377f47c2cd4e6bb84 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:16:08 +0100 Subject: [PATCH 20/45] updated Android implementation to support String output --- .../io/flutter/plugins/camera/Camera.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 84a1cbc254be..43bf35cec487 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -33,6 +33,8 @@ import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.media.MediaRecorderBuilder; @@ -137,17 +139,28 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { } @SuppressLint("MissingPermission") - public void open(Integer imageFormatGroup) throws CameraAccessException { + public void open(String imageFormatGroup) throws CameraAccessException { + Integer imageFormat; + HashMap imageFormatMap = new HashMap<>(); + // Current supported outputs + imageFormatMap.put("YUV420", 35); + imageFormatMap.put("JPEG", 256); + pictureImageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); - imageFormatGroup = imageFormatGroup != null? imageFormatGroup : ImageFormat.YUV_420_888; + if (VERSION.SDK_INT >= VERSION_CODES.N){ + imageFormat = imageFormatMap.getOrDefault(imageFormatGroup, ImageFormat.YUV_420_888); + } else { + imageFormat = imageFormatMap.get(imageFormatGroup); + if (imageFormat == null) imageFormat = ImageFormat.YUV_420_888; + } // Used to steam image byte data to dart side. imageStreamReader = ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), imageFormatGroup, 2); + previewSize.getWidth(), previewSize.getHeight(), imageFormat, 2); cameraManager.openCamera( cameraName, From 7f06e7988545e7d162ea50ae83eda0f39eb55ffe Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:17:46 +0100 Subject: [PATCH 21/45] removed getOrDefault --- .../main/java/io/flutter/plugins/camera/Camera.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 43bf35cec487..ec912d5fc19c 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -140,7 +140,6 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { @SuppressLint("MissingPermission") public void open(String imageFormatGroup) throws CameraAccessException { - Integer imageFormat; HashMap imageFormatMap = new HashMap<>(); // Current supported outputs imageFormatMap.put("YUV420", 35); @@ -150,12 +149,9 @@ public void open(String imageFormatGroup) throws CameraAccessException { ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); - if (VERSION.SDK_INT >= VERSION_CODES.N){ - imageFormat = imageFormatMap.getOrDefault(imageFormatGroup, ImageFormat.YUV_420_888); - } else { - imageFormat = imageFormatMap.get(imageFormatGroup); - if (imageFormat == null) imageFormat = ImageFormat.YUV_420_888; - } + + Integer imageFormat = imageFormatMap.get(imageFormatGroup); + if (imageFormat == null) imageFormat = ImageFormat.YUV_420_888; // Used to steam image byte data to dart side. imageStreamReader = From c887e9dbae76f08e054de723cea6c5b0c0e981fd Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:29:39 +0100 Subject: [PATCH 22/45] Updated camera implementation to use ImageFormatGroupName; Updated to Dart 2.7.0 to support extensions; --- .../io/flutter/plugins/camera/Camera.java | 1 - packages/camera/camera/example/pubspec.yaml | 2 +- packages/camera/camera/lib/camera.dart | 3 +- .../camera/lib/src/camera_controller.dart | 4 +-- .../camera/camera/lib/src/camera_image.dart | 33 +----------------- .../camera/lib/utils/image_format_utils.dart | 34 ------------------- packages/camera/camera/pubspec.yaml | 2 +- .../camera/camera/test/camera_image_test.dart | 1 + packages/camera/camera/test/camera_test.dart | 28 +++------------ .../lib/src/types/types.dart | 1 + 10 files changed, 13 insertions(+), 96 deletions(-) delete mode 100644 packages/camera/camera/lib/utils/image_format_utils.dart diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index ec912d5fc19c..5e29740c6991 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -149,7 +149,6 @@ public void open(String imageFormatGroup) throws CameraAccessException { ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); - Integer imageFormat = imageFormatMap.get(imageFormatGroup); if (imageFormat == null) imageFormat = ImageFormat.YUV_420_888; diff --git a/packages/camera/camera/example/pubspec.yaml b/packages/camera/camera/example/pubspec.yaml index 0d1f03bef437..5d59ebf75c62 100644 --- a/packages/camera/camera/example/pubspec.yaml +++ b/packages/camera/camera/example/pubspec.yaml @@ -22,5 +22,5 @@ flutter: uses-material-design: true environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.9.1+hotfix.4 <2.0.0" diff --git a/packages/camera/camera/lib/camera.dart b/packages/camera/camera/lib/camera.dart index 6c6214e96951..cd788f23c6ac 100644 --- a/packages/camera/camera/lib/camera.dart +++ b/packages/camera/camera/lib/camera.dart @@ -13,4 +13,5 @@ export 'package:camera_platform_interface/camera_platform_interface.dart' CameraLensDirection, FlashMode, ResolutionPreset, - XFile; + XFile, + ImageFormatGroup; diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 3c8fe1f8ea74..86b292463528 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -10,8 +10,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../utils/image_format_utils.dart'; - final MethodChannel _channel = const MethodChannel('plugins.flutter.io/camera'); /// Signature for a callback receiving the a camera image. @@ -208,7 +206,7 @@ class CameraController extends ValueNotifier { await CameraPlatform.instance.initializeCamera( _cameraId, - imageFormatGroup: imageFormatGroupAsIntegerValue(imageFormatGroup), + imageFormatGroup: imageFormatGroup, ); value = value.copyWith( diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index 36c8983e8f56..bdec4a1994ad 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -6,6 +6,7 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:camera_platform_interface/camera_platform_interface.dart'; /// A single color plane of image data. /// @@ -41,38 +42,6 @@ class Plane { final int width; } -// TODO:(bmparr) Turn [ImageFormatGroup] to a class with int values. -/// Group of image formats that are comparable across Android and iOS platforms. -enum ImageFormatGroup { - /// The image format does not fit into any specific group. - unknown, - - /// Multi-plane YUV 420 format. - /// - /// This format is a generic YCbCr format, capable of describing any 4:2:0 - /// chroma-subsampled planar or semiplanar buffer (but not fully interleaved), - /// with 8 bits per color sample. - /// - /// On Android, this is `android.graphics.ImageFormat.YUV_420_888`. See - /// https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888 - /// - /// On iOS, this is `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`. See - /// https://developer.apple.com/documentation/corevideo/1563591-pixel_format_identifiers/kcvpixelformattype_420ypcbcr8biplanarvideorange?language=objc - yuv420, - - /// 32-bit BGRA. - /// - /// 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#JPEG - jpeg, -} - /// Describes how pixels are represented in an image. class ImageFormat { ImageFormat._fromPlatformData(this.raw) : group = _asImageFormatGroup(raw); diff --git a/packages/camera/camera/lib/utils/image_format_utils.dart b/packages/camera/camera/lib/utils/image_format_utils.dart deleted file mode 100644 index 9e62b1d45b94..000000000000 --- a/packages/camera/camera/lib/utils/image_format_utils.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/foundation.dart'; - -import '../camera.dart'; - -/// Converts [ImageFormatGroup] to integer definition of the raw format -int imageFormatGroupAsIntegerValue(ImageFormatGroup imageFormatGroup) { - if (defaultTargetPlatform == TargetPlatform.iOS) { - switch (imageFormatGroup) { - // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange - case ImageFormatGroup.yuv420: - return 875704438; - // kCVPixelFormatType_32BGRA - case ImageFormatGroup.bgra8888: - return 1111970369; - case ImageFormatGroup.jpeg: - case ImageFormatGroup.unknown: - return 0; - } - } else if (defaultTargetPlatform == TargetPlatform.android) { - switch (imageFormatGroup) { - // kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange - case ImageFormatGroup.yuv420: - return 35; - // kCVPixelFormatType_32BGRA - case ImageFormatGroup.bgra8888: - case ImageFormatGroup.unknown: - return 0; - case ImageFormatGroup.jpeg: - return 256; - } - } - // unknown ImageFormatGroup or unsupported platform - return 0; -} \ No newline at end of file diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index d823dd383281..c28f1442f296 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -31,5 +31,5 @@ flutter: pluginClass: CameraPlugin environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" flutter: ">=1.12.13+hotfix.5" diff --git a/packages/camera/camera/test/camera_image_test.dart b/packages/camera/camera/test/camera_image_test.dart index c8f808f2c1a1..c7f8e4320434 100644 --- a/packages/camera/camera/test/camera_image_test.dart +++ b/packages/camera/camera/test/camera_image_test.dart @@ -5,6 +5,7 @@ import 'dart:typed_data'; import 'package:camera/camera.dart'; +import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index 1337f9a584fa..9f47f5a9dee9 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:ui'; import 'package:camera/camera.dart'; -import 'package:camera/utils/image_format_utils.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -85,11 +84,6 @@ void main() { CameraPlatform.instance = MockCameraPlatform(); }); - tearDown(() { - (CameraPlatform.instance as MockCameraPlatform).log.clear(); - }); - - test('Can be initialized', () async { CameraController cameraController = CameraController( CameraDescription( @@ -170,7 +164,6 @@ void main() { }); test('initialize() sets imageFormat', () async { - debugDefaultTargetPlatformOverride = TargetPlatform.android; CameraController cameraController = CameraController( CameraDescription( @@ -181,12 +174,9 @@ void main() { imageFormatGroup: ImageFormatGroup.yuv420, ); await cameraController.initialize(); - - expect((CameraPlatform.instance as MockCameraPlatform).log.first, { - 'method': 'initializeCamera', - 'cameraId': 13, - 'imageFormatGroup': imageFormatGroupAsIntegerValue(ImageFormatGroup.yuv420), - }); + verify(CameraPlatform.instance + .initializeCamera(13, imageFormatGroup: ImageFormatGroup.yuv420)) + .called(1); }); test('prepareForVideoRecording() calls $CameraPlatform ', () async { @@ -636,17 +626,9 @@ void main() { class MockCameraPlatform extends Mock with MockPlatformInterfaceMixin implements CameraPlatform { - final log = []; - @override - Future initializeCamera(int cameraId, {int imageFormatGroup}) { - log.add({ - 'method': 'initializeCamera', - 'cameraId': cameraId, - 'imageFormatGroup': imageFormatGroup, - }); - return null; - } + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}); @override Future> availableCameras() => diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 3a89a1021e95..62c9f65319f2 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -6,3 +6,4 @@ export 'camera_description.dart'; export 'resolution_preset.dart'; export 'camera_exception.dart'; export 'flash_mode.dart'; +export 'image_format_group.dart'; \ No newline at end of file From 18336f90902bc47b30a41399d57f6a7887c9068b Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:30:43 +0100 Subject: [PATCH 23/45] removed unused import --- .../android/src/main/java/io/flutter/plugins/camera/Camera.java | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 5e29740c6991..b05feb12f996 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -33,7 +33,6 @@ import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; From cf6345cd35e9aa16d875af040f993692b6687947 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 14:40:14 +0100 Subject: [PATCH 24/45] Export image_format_group.dart in types.dart --- .../camera/camera_platform_interface/lib/src/types/types.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 3a89a1021e95..62c9f65319f2 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -6,3 +6,4 @@ export 'camera_description.dart'; export 'resolution_preset.dart'; export 'camera_exception.dart'; export 'flash_mode.dart'; +export 'image_format_group.dart'; \ No newline at end of file From 81799a7cd60d89c42058f08c2334a3d50458f365 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 15:21:21 +0100 Subject: [PATCH 25/45] Changed enum values to lowercase --- .../lib/src/types/image_format_group.dart | 16 ++++++++-------- .../method_channel_camera_test.dart | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 06bd111bc6d2..59e47064f3a4 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -34,33 +34,33 @@ enum ImageFormatGroup { /// Extension on [ImageFormatGroup] to stringify the enum extension ImageFormatGroupName on ImageFormatGroup { /// returns a String value for [ImageFormatGroup] - /// returns 'UNKNOWN' if platform is not supported + /// returns 'unknown' if platform is not supported /// or if [ImageFormatGroup] is not supported for the platform String name() { if (defaultTargetPlatform == TargetPlatform.android) { switch (this) { case ImageFormatGroup.jpeg: - return 'JPEG'; + return 'jpeg'; case ImageFormatGroup.yuv420: - return 'YUV420'; + return 'yuv420'; case ImageFormatGroup.bgra8888: case ImageFormatGroup.unknown: default: - return 'UNKNOWN'; + return 'unknown'; } } else if (defaultTargetPlatform == TargetPlatform.iOS) { switch (this) { case ImageFormatGroup.bgra8888: - return 'BGRA888'; + return 'bgra8888'; case ImageFormatGroup.yuv420: - return 'YUV420'; + return 'yuv420'; case ImageFormatGroup.jpeg: case ImageFormatGroup.unknown: default: - return 'UNKNOWN'; + return 'unknown'; } } // unsupported platform - return 'UNKNOWN'; + return 'unknown'; } } diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart index 3763da4df8da..5aa44d544508 100644 --- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart +++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart @@ -26,7 +26,7 @@ void main() { methods: { 'create': { 'cameraId': 1, - 'imageFormatGroup': 'UNKNOWN', + 'imageFormatGroup': 'unknown', } }); final camera = MethodChannelCamera(); @@ -112,7 +112,7 @@ void main() { methods: { 'create': { 'cameraId': 1, - 'imageFormatGroup': 'UNKNOWN', + 'imageFormatGroup': 'unknown', }, 'initialize': null }); @@ -136,7 +136,7 @@ void main() { 'initialize', arguments: { 'cameraId': 1, - 'imageFormatGroup': 'UNKNOWN', + 'imageFormatGroup': 'unknown', }, ), ]); From ab15e89a7a0dc6ab0a4db0ab690eb089eabc3447 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 15:35:31 +0100 Subject: [PATCH 26/45] Added ImageFormatGroup test --- .../test/types/image_group_test.dart | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/camera/camera_platform_interface/test/types/image_group_test.dart diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart new file mode 100644 index 000000000000..6c72498506a6 --- /dev/null +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -0,0 +1,22 @@ +import 'dart:io'; + +import 'package:camera_platform_interface/src/types/types.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('$ImageFormatGroup tests', () { + test('ImageFormatGroupName extension returns correct values', () { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + expect(ImageFormatGroup.jpeg.name(), 'jpeg'); + expect(ImageFormatGroup.yuv420.name(), 'yuv420'); + expect(ImageFormatGroup.bgra8888.name(), 'unknown'); + expect(ImageFormatGroup.unknown.name(), 'unknown'); + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + expect(ImageFormatGroup.bgra8888.name(), 'bgra8888'); + expect(ImageFormatGroup.yuv420.name(), 'yuv420'); + expect(ImageFormatGroup.jpeg.name(), 'unknown'); + expect(ImageFormatGroup.unknown.name(), 'unknown'); + }); + }); +} \ No newline at end of file From 098fd76211fb6b05fb5122cf41b0981e12d7a050 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 15:36:21 +0100 Subject: [PATCH 27/45] Fixed formatting --- .../test/types/image_group_test.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart index 6c72498506a6..7c8a45a3f70a 100644 --- a/packages/camera/camera_platform_interface/test/types/image_group_test.dart +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:camera_platform_interface/src/types/types.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -19,4 +17,4 @@ void main() { expect(ImageFormatGroup.unknown.name(), 'unknown'); }); }); -} \ No newline at end of file +} From 6b65ed1c06cbc2c79c682a2e642a3ce5af1755ef Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 15:57:39 +0100 Subject: [PATCH 28/45] made enum strings lowercase --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index b05feb12f996..216d1c5f72a4 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -141,8 +141,8 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { public void open(String imageFormatGroup) throws CameraAccessException { HashMap imageFormatMap = new HashMap<>(); // Current supported outputs - imageFormatMap.put("YUV420", 35); - imageFormatMap.put("JPEG", 256); + imageFormatMap.put("yuv420", 35); + imageFormatMap.put("jpeg", 256); pictureImageReader = ImageReader.newInstance( From f8d9e4c1171ee40a74bc7fcaa81829d6fb55214e Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 16:00:25 +0100 Subject: [PATCH 29/45] Removed target platform switch. --- .../lib/src/types/image_format_group.dart | 38 ++++++------------- .../test/types/image_group_test.dart | 9 +---- 2 files changed, 12 insertions(+), 35 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index 59e47064f3a4..df1837a856c5 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -1,5 +1,3 @@ -import 'package:flutter/foundation.dart'; - /// Group of image formats that are comparable across Android and iOS platforms. enum ImageFormatGroup { /// The image format does not fit into any specific group. @@ -37,30 +35,16 @@ extension ImageFormatGroupName on ImageFormatGroup { /// returns 'unknown' if platform is not supported /// or if [ImageFormatGroup] is not supported for the platform String name() { - if (defaultTargetPlatform == TargetPlatform.android) { - switch (this) { - case ImageFormatGroup.jpeg: - return 'jpeg'; - case ImageFormatGroup.yuv420: - return 'yuv420'; - case ImageFormatGroup.bgra8888: - case ImageFormatGroup.unknown: - default: - return 'unknown'; - } - } else if (defaultTargetPlatform == TargetPlatform.iOS) { - switch (this) { - case ImageFormatGroup.bgra8888: - return 'bgra8888'; - case ImageFormatGroup.yuv420: - return 'yuv420'; - case ImageFormatGroup.jpeg: - case ImageFormatGroup.unknown: - default: - return 'unknown'; - } + switch (this) { + case ImageFormatGroup.bgra8888: + return 'bgra8888'; + case ImageFormatGroup.yuv420: + return 'yuv420'; + case ImageFormatGroup.jpeg: + return 'jpeg'; + case ImageFormatGroup.unknown: + default: + return 'unknown'; } - // unsupported platform - return 'unknown'; } -} +} \ No newline at end of file diff --git a/packages/camera/camera_platform_interface/test/types/image_group_test.dart b/packages/camera/camera_platform_interface/test/types/image_group_test.dart index 7c8a45a3f70a..c49b2f03a7a0 100644 --- a/packages/camera/camera_platform_interface/test/types/image_group_test.dart +++ b/packages/camera/camera_platform_interface/test/types/image_group_test.dart @@ -1,19 +1,12 @@ import 'package:camera_platform_interface/src/types/types.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('$ImageFormatGroup tests', () { test('ImageFormatGroupName extension returns correct values', () { - debugDefaultTargetPlatformOverride = TargetPlatform.android; - expect(ImageFormatGroup.jpeg.name(), 'jpeg'); - expect(ImageFormatGroup.yuv420.name(), 'yuv420'); - expect(ImageFormatGroup.bgra8888.name(), 'unknown'); - expect(ImageFormatGroup.unknown.name(), 'unknown'); - debugDefaultTargetPlatformOverride = TargetPlatform.iOS; expect(ImageFormatGroup.bgra8888.name(), 'bgra8888'); expect(ImageFormatGroup.yuv420.name(), 'yuv420'); - expect(ImageFormatGroup.jpeg.name(), 'unknown'); + expect(ImageFormatGroup.jpeg.name(), 'jpeg'); expect(ImageFormatGroup.unknown.name(), 'unknown'); }); }); From 8936a7f1d3123865e3790815bd626c42ae4f3615 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 16:27:54 +0100 Subject: [PATCH 30/45] Fixed formatting --- .../lib/src/method_channel/method_channel_camera.dart | 3 ++- .../lib/src/platform_interface/camera_platform.dart | 3 ++- .../lib/src/types/image_format_group.dart | 2 +- .../camera/camera_platform_interface/lib/src/types/types.dart | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart index 8a8bb5339b85..4f92ca62dbb1 100644 --- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart +++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart @@ -76,7 +76,8 @@ class MethodChannelCamera extends CameraPlatform { } @override - Future initializeCamera(int cameraId, {ImageFormatGroup imageFormatGroup}) { + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}) { _channels.putIfAbsent(cameraId, () { final channel = MethodChannel('flutter.io/cameraPlugin/camera$cameraId'); channel.setMethodCallHandler( diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart index 6ec977047902..3b1ae7932149 100644 --- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart +++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart @@ -57,7 +57,8 @@ abstract class CameraPlatform extends PlatformInterface { /// [imageFormatGroup] is used to specify the image formatting used. /// On Android this defaults to ImageFormat.YUV_420_888 and applies only to the imageStream. /// On iOS this defaults to kCVPixelFormatType_32BGRA. - Future initializeCamera(int cameraId, {ImageFormatGroup imageFormatGroup}) { + Future initializeCamera(int cameraId, + {ImageFormatGroup imageFormatGroup}) { throw UnimplementedError('initializeCamera() is not implemented.'); } diff --git a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart index df1837a856c5..3d2c0180fe65 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/image_format_group.dart @@ -47,4 +47,4 @@ extension ImageFormatGroupName on ImageFormatGroup { return 'unknown'; } } -} \ No newline at end of file +} diff --git a/packages/camera/camera_platform_interface/lib/src/types/types.dart b/packages/camera/camera_platform_interface/lib/src/types/types.dart index 62c9f65319f2..024ba10efe39 100644 --- a/packages/camera/camera_platform_interface/lib/src/types/types.dart +++ b/packages/camera/camera_platform_interface/lib/src/types/types.dart @@ -6,4 +6,4 @@ export 'camera_description.dart'; export 'resolution_preset.dart'; export 'camera_exception.dart'; export 'flash_mode.dart'; -export 'image_format_group.dart'; \ No newline at end of file +export 'image_format_group.dart'; From 71f77f4fcd6b6ff5a009ab1133b7ea34a0e8432e Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 16:46:10 +0100 Subject: [PATCH 31/45] Updated Android implementation --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 8 +++++++- packages/camera/camera/example/lib/main.dart | 8 ++------ packages/camera/camera/lib/src/camera_image.dart | 4 ++-- packages/camera/camera/pubspec.yaml | 3 ++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 216d1c5f72a4..dc1616a10784 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -1,5 +1,6 @@ package io.flutter.plugins.camera; +import static android.content.ContentValues.TAG; import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; import static io.flutter.plugins.camera.CameraUtils.computeBestPreviewSize; @@ -29,6 +30,7 @@ import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; +import android.util.Log; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; @@ -149,7 +151,11 @@ public void open(String imageFormatGroup) throws CameraAccessException { captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); Integer imageFormat = imageFormatMap.get(imageFormatGroup); - if (imageFormat == null) imageFormat = ImageFormat.YUV_420_888; + if (imageFormat == null) { + Log.w(TAG, + "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); + imageFormat = ImageFormat.YUV_420_888; + } // Used to steam image byte data to dart side. imageStreamReader = diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 66f40542d11e..7da370aa9c80 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -348,12 +348,8 @@ class _CameraExampleHomeState extends State if (controller != null) { await controller.dispose(); } - controller = CameraController( - cameraDescription, - ResolutionPreset.medium, - enableAudio: enableAudio, - imageFormatGroup: ImageFormatGroup.jpeg - ); + controller = CameraController(cameraDescription, ResolutionPreset.medium, + enableAudio: enableAudio, imageFormatGroup: ImageFormatGroup.jpeg); // If the controller is updated then update the UI. controller.addListener(() { diff --git a/packages/camera/camera/lib/src/camera_image.dart b/packages/camera/camera/lib/src/camera_image.dart index bdec4a1994ad..dffa5066d14f 100644 --- a/packages/camera/camera/lib/src/camera_image.dart +++ b/packages/camera/camera/lib/src/camera_image.dart @@ -62,10 +62,10 @@ class ImageFormat { ImageFormatGroup _asImageFormatGroup(dynamic rawFormat) { if (defaultTargetPlatform == TargetPlatform.android) { switch (rawFormat) { - // android.graphics.ImageFormat.YUV_420_888 + // android.graphics.ImageFormat.YUV_420_888 case 35: return ImageFormatGroup.yuv420; - // android.graphics.ImageFormat.JPEG + // android.graphics.ImageFormat.JPEG case 256: return ImageFormatGroup.jpeg; } diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index c28f1442f296..267246af500a 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -8,7 +8,8 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.0.4 + camera_platform_interface: + path: ../camera_platform_interface dev_dependencies: path_provider: ^0.5.0 From 2b6751bff8a9f12ed9eaa3a663bd1885d16e6fb0 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 16:51:00 +0100 Subject: [PATCH 32/45] Updated iOS implementation --- packages/camera/camera/ios/Classes/CameraPlugin.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index c073898d4a0a..fd02c48c4f4c 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -992,15 +992,16 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSDictionary *argsMap = call.arguments; NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { - int videoFormatValue = ((NSNumber *)argsMap[@"imageFormatGroup"]).unsignedIntegerValue; + NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); switch (videoFormatValue) { - case 1111970369: + case "bgra8888": videoFormat = kCVPixelFormatType_32BGRA; break; - case 875704438: + case "yuv420": videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; break; default: + NSLog(@"Unsupported ImageFormatGroup, defaulting to bgra8888"); videoFormat = kCVPixelFormatType_32BGRA; } From 7e65ac105669e625860189aaa65285be0c8714e7 Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 16:58:03 +0100 Subject: [PATCH 33/45] updated log message for unsupported ImageFormatGroup --- packages/camera/camera/ios/Classes/CameraPlugin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index fd02c48c4f4c..0dc4f39421e1 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -1001,7 +1001,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; break; default: - NSLog(@"Unsupported ImageFormatGroup, defaulting to bgra8888"); + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); videoFormat = kCVPixelFormatType_32BGRA; } From 5f1a17c892c14e06cc02d9b9c00e985799f7cedf Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 17:05:31 +0100 Subject: [PATCH 34/45] Updated Android implementation --- .../java/io/flutter/plugins/camera/Camera.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index dc1616a10784..20140bd983a2 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -80,6 +80,7 @@ public class Camera { private int currentOrientation = ORIENTATION_UNKNOWN; private FlashMode flashMode; private PictureCaptureRequest pictureCaptureRequest; + private static HashMap supportedImageFormats; public Camera( final Activity activity, @@ -125,6 +126,12 @@ public void onOrientationChanged(int i) { new CameraZoom( characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)); + supportedImageFormats = new HashMap<>(); + // Current supported outputs + { + supportedImageFormats.put("yuv420", 35); + supportedImageFormats.put("jpeg", 256); + }; } private void prepareMediaRecorder(String outputFilePath) throws IOException { @@ -141,16 +148,11 @@ private void prepareMediaRecorder(String outputFilePath) throws IOException { @SuppressLint("MissingPermission") public void open(String imageFormatGroup) throws CameraAccessException { - HashMap imageFormatMap = new HashMap<>(); - // Current supported outputs - imageFormatMap.put("yuv420", 35); - imageFormatMap.put("jpeg", 256); - pictureImageReader = ImageReader.newInstance( captureSize.getWidth(), captureSize.getHeight(), ImageFormat.JPEG, 2); - Integer imageFormat = imageFormatMap.get(imageFormatGroup); + Integer imageFormat = supportedImageFormats.get(imageFormatGroup); if (imageFormat == null) { Log.w(TAG, "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); From 18efce613f8f55863064eef467466e4f99c4894f Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Wed, 23 Dec 2020 17:07:52 +0100 Subject: [PATCH 35/45] fixed period in docs --- packages/camera/camera/lib/src/camera_controller.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 86b292463528..cd4d654e9821 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -161,7 +161,7 @@ class CameraController extends ValueNotifier { /// The [ImageFormatGroup] describes the output of the raw image format. /// - /// When null the imageFormat will fallback to the platforms default + /// When null the imageFormat will fallback to the platforms default. final ImageFormatGroup imageFormatGroup; int _cameraId; From 06ec92d1d798b78642d9ddc013af2464cbbe2136 Mon Sep 17 00:00:00 2001 From: anniek Date: Wed, 23 Dec 2020 17:38:45 +0100 Subject: [PATCH 36/45] Switch change to if-statement --- .../camera/camera/ios/Classes/CameraPlugin.m | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 0dc4f39421e1..ab6af28a2837 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -993,17 +993,13 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); - switch (videoFormatValue) { - case "bgra8888": - videoFormat = kCVPixelFormatType_32BGRA; - break; - case "yuv420": - videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; - break; - default: - NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); - videoFormat = kCVPixelFormatType_32BGRA; - + if ([videoFormatValue isEqualToString:@"bgra8888"]) { + videoFormat = kCVPixelFormatType_32BGRA; + } else if ([videoFormatValue isEqualToString:@"yuv420"]) { + videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + } else { + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); + videoFormat = kCVPixelFormatType_32BGRA; } __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ From be3bb3dfe44c0f25f20d2d832a5d678beaf75854 Mon Sep 17 00:00:00 2001 From: Daniel Roek Date: Thu, 24 Dec 2020 12:06:16 +0100 Subject: [PATCH 37/45] Moved switching videoFormat to method in iOS --- .../camera/camera/ios/Classes/CameraPlugin.m | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index ab6af28a2837..f987e9d3eca3 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -152,6 +152,17 @@ static AVCaptureFlashMode getFlashModeForString(NSString *mode) { } } +static OSType getVideoFormatFromString(NSString *videoFormatString) { + if([videoFormatString isEqualToString:@"bgra8888"]){ + return kCVPixelFormatType_32BGRA; + } else if([videoFormatString isEqualToString:@"yuv420"]) { + return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + } else { + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); + return kCVPixelFormatType_32BGRA; + } +} + // Mirrors ResolutionPreset in camera.dart typedef enum { veryLow, @@ -993,14 +1004,8 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); - if ([videoFormatValue isEqualToString:@"bgra8888"]) { - videoFormat = kCVPixelFormatType_32BGRA; - } else if ([videoFormatValue isEqualToString:@"yuv420"]) { - videoFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; - } else { - NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); - videoFormat = kCVPixelFormatType_32BGRA; - } + videoFormat = getVideoFormatFromString(videoFormatValue); + __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; From b0a67fc4cc687ca98be0101cd288337e56750345 Mon Sep 17 00:00:00 2001 From: Daniel Roek Date: Thu, 24 Dec 2020 12:16:10 +0100 Subject: [PATCH 38/45] Implemented feedback --- .../main/java/io/flutter/plugins/camera/Camera.java | 12 ++++++------ packages/camera/camera/example/lib/main.dart | 8 ++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 20140bd983a2..971792d9540b 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -81,6 +81,12 @@ public class Camera { private FlashMode flashMode; private PictureCaptureRequest pictureCaptureRequest; private static HashMap supportedImageFormats; + // Current supported outputs + static { + supportedImageFormats = new HashMap<>(); + supportedImageFormats.put("yuv420", 35); + supportedImageFormats.put("jpeg", 256); + }; public Camera( final Activity activity, @@ -126,12 +132,6 @@ public void onOrientationChanged(int i) { new CameraZoom( characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), characteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM)); - supportedImageFormats = new HashMap<>(); - // Current supported outputs - { - supportedImageFormats.put("yuv420", 35); - supportedImageFormats.put("jpeg", 256); - }; } private void prepareMediaRecorder(String outputFilePath) throws IOException { diff --git a/packages/camera/camera/example/lib/main.dart b/packages/camera/camera/example/lib/main.dart index 7da370aa9c80..850e22e69315 100644 --- a/packages/camera/camera/example/lib/main.dart +++ b/packages/camera/camera/example/lib/main.dart @@ -348,8 +348,12 @@ class _CameraExampleHomeState extends State if (controller != null) { await controller.dispose(); } - controller = CameraController(cameraDescription, ResolutionPreset.medium, - enableAudio: enableAudio, imageFormatGroup: ImageFormatGroup.jpeg); + controller = CameraController( + cameraDescription, + ResolutionPreset.medium, + enableAudio: enableAudio, + imageFormatGroup: ImageFormatGroup.jpeg, + ); // If the controller is updated then update the UI. controller.addListener(() { From 0e04029879a32e38d33a1fcbfb444e4265a73c78 Mon Sep 17 00:00:00 2001 From: Daniel Roek Date: Thu, 24 Dec 2020 12:19:13 +0100 Subject: [PATCH 39/45] fixed formatting --- .../camera/camera/ios/Classes/CameraPlugin.m | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index f987e9d3eca3..25ae13fc898e 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -153,14 +153,14 @@ static AVCaptureFlashMode getFlashModeForString(NSString *mode) { } static OSType getVideoFormatFromString(NSString *videoFormatString) { - if([videoFormatString isEqualToString:@"bgra8888"]){ - return kCVPixelFormatType_32BGRA; - } else if([videoFormatString isEqualToString:@"yuv420"]) { - return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; - } else { - NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); - return kCVPixelFormatType_32BGRA; - } + if([videoFormatString isEqualToString:@"bgra8888"]){ + return kCVPixelFormatType_32BGRA; + } else if([videoFormatString isEqualToString:@"yuv420"]) { + return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + } else { + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); + return kCVPixelFormatType_32BGRA; + } } // Mirrors ResolutionPreset in camera.dart @@ -1003,8 +1003,8 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re NSDictionary *argsMap = call.arguments; NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue; if ([@"initialize" isEqualToString:call.method]) { - NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); - videoFormat = getVideoFormatFromString(videoFormatValue); + NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); + videoFormat = getVideoFormatFromString(videoFormatValue); __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ From 375396c0284b90d3d26b423655f73c77b8f1d1eb Mon Sep 17 00:00:00 2001 From: Daniel Roek Date: Thu, 24 Dec 2020 12:28:04 +0100 Subject: [PATCH 40/45] fixed mistakingly removed bracket --- packages/camera/camera/ios/Classes/CameraPlugin.m | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 0111d623a70a..69bbc6a417e0 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -184,6 +184,7 @@ static AVCaptureFlashMode getAVCaptureFlashModeForFlashMode(FlashMode mode) { case FlashModeTorch: default: return -1; + } } // Mirrors ResolutionPreset in camera.dart From 5ec0af986e67e0b5aeacff091ca6ce9477ef8f3f Mon Sep 17 00:00:00 2001 From: Daniel Roek Date: Thu, 24 Dec 2020 14:23:37 +0100 Subject: [PATCH 41/45] fixed formatting --- .../java/io/flutter/plugins/camera/Camera.java | 7 ++----- packages/camera/camera/ios/Classes/CameraPlugin.m | 14 +++++++------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 22408912a758..519ddfd4e0e7 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -35,7 +35,6 @@ import android.view.OrientationEventListener; import android.view.Surface; import androidx.annotation.NonNull; - import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugins.camera.media.MediaRecorderBuilder; @@ -154,15 +153,13 @@ public void open(String imageFormatGroup) throws CameraAccessException { Integer imageFormat = supportedImageFormats.get(imageFormatGroup); if (imageFormat == null) { - Log.w(TAG, - "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); + Log.w(TAG, "The selected imageFormatGroup is not supported by Android. Defaulting to yuv420"); imageFormat = ImageFormat.YUV_420_888; } // Used to steam image byte data to dart side. imageStreamReader = - ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), imageFormat, 2); + ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(), imageFormat, 2); cameraManager.openCamera( cameraName, diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 69bbc6a417e0..7495e8195f44 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -163,13 +163,13 @@ static FlashMode getFlashModeForString(NSString *mode) { } static OSType getVideoFormatFromString(NSString *videoFormatString) { - if([videoFormatString isEqualToString:@"bgra8888"]){ - return kCVPixelFormatType_32BGRA; - } else if([videoFormatString isEqualToString:@"yuv420"]) { - return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + if ([videoFormatString isEqualToString:@"bgra8888"]) { + return kCVPixelFormatType_32BGRA; + } else if ([videoFormatString isEqualToString:@"yuv420"]) { + return kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; } else { - NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); - return kCVPixelFormatType_32BGRA; + NSLog(@"The selected imageFormatGroup is not supported by iOS. Defaulting to brga8888"); + return kCVPixelFormatType_32BGRA; } } @@ -1064,7 +1064,7 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re if ([@"initialize" isEqualToString:call.method]) { NSString *videoFormatValue = ((NSString *)argsMap[@"imageFormatGroup"]); videoFormat = getVideoFormatFromString(videoFormatValue); - + __weak CameraPlugin *weakSelf = self; _camera.onFrameAvailable = ^{ [weakSelf.registry textureFrameAvailable:cameraId]; From 79538205805efede4bbdc6bec2bb0c8651eb3f4e Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 4 Jan 2021 16:44:57 +0100 Subject: [PATCH 42/45] Updated version --- packages/camera/camera/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/camera/camera/CHANGELOG.md b/packages/camera/camera/CHANGELOG.md index 3bb1b0639c97..787057a17f08 100644 --- a/packages/camera/camera/CHANGELOG.md +++ b/packages/camera/camera/CHANGELOG.md @@ -1,6 +1,10 @@ +## 0.6.5 + +* Adds ImageFormat selection for ImageStream and Video(iOS only). + ## 0.6.4+1 -* Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash +* Added closeCaptureSession() to stopVideoRecording in Camera.java to fix an Android 6 crash. ## 0.6.4 From 8ea2454ee301e2b19547bf9d6a560aeef3f3f62a Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 4 Jan 2021 16:56:02 +0100 Subject: [PATCH 43/45] Updated version --- packages/camera/camera/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera/pubspec.yaml b/packages/camera/camera/pubspec.yaml index 7ed9864fb67d..7c275c2268cd 100644 --- a/packages/camera/camera/pubspec.yaml +++ b/packages/camera/camera/pubspec.yaml @@ -8,7 +8,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera dependencies: flutter: sdk: flutter - camera_platform_interface: ^1.4.0 + camera_platform_interface: ^1.3.0 pedantic: ^1.8.0 dev_dependencies: From f904cbf8e72d4f9ad932aa2409e0fe1659271a8f Mon Sep 17 00:00:00 2001 From: "daniel.roek" Date: Mon, 4 Jan 2021 17:12:21 +0100 Subject: [PATCH 44/45] fixed formatting --- .../android/src/main/java/io/flutter/plugins/camera/Camera.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 70124f3ad062..c26a7d570ec0 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -34,9 +34,9 @@ import android.os.Build.VERSION_CODES; import android.os.Handler; import android.os.Looper; +import android.util.Log; import android.util.Range; import android.util.Rational; -import android.util.Log; import android.util.Size; import android.view.OrientationEventListener; import android.view.Surface; From 23e7753ca2152e7d641b3e777ddf1a84dc7175d4 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Mon, 11 Jan 2021 08:42:13 +0100 Subject: [PATCH 45/45] Define TAG correctly --- .../src/main/java/io/flutter/plugins/camera/Camera.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 0551e97a0fef..fd7f4d67fa04 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -1,6 +1,5 @@ package io.flutter.plugins.camera; -import static android.content.ContentValues.TAG; import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; import static io.flutter.plugins.camera.CameraUtils.computeBestPreviewSize; @@ -68,6 +67,8 @@ interface ErrorCallback { } public class Camera { + private static final String TAG = "Camera"; + private final SurfaceTextureEntry flutterTexture; private final CameraManager cameraManager; private final OrientationEventListener orientationEventListener; @@ -100,13 +101,13 @@ public class Camera { private boolean useAutoFocus = true; private Range fpsRange; - private static HashMap supportedImageFormats; + private static final HashMap supportedImageFormats; // Current supported outputs static { supportedImageFormats = new HashMap<>(); supportedImageFormats.put("yuv420", 35); supportedImageFormats.put("jpeg", 256); - }; + } public Camera( final Activity activity,