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

Commit 21fb3f7

Browse files
authored
Merge pull request #1 from tr8team/feature/ap/take-picture-without-rotation
Add option to take picture without rotation
2 parents 946b37b + b676193 commit 21fb3f7

File tree

5 files changed

+45
-12
lines changed

5 files changed

+45
-12
lines changed

packages/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ SurfaceTextureEntry getFlutterTexture() {
223223
return flutterTexture;
224224
}
225225

226-
public void takePicture(String filePath, @NonNull final Result result) {
226+
public void takePicture(String filePath, boolean shouldAutoRotate, @NonNull final Result result) {
227227
final File file = new File(filePath);
228228

229229
if (file.exists()) {
@@ -248,7 +248,8 @@ public void takePicture(String filePath, @NonNull final Result result) {
248248
final CaptureRequest.Builder captureBuilder =
249249
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
250250
captureBuilder.addTarget(pictureImageReader.getSurface());
251-
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getMediaOrientation());
251+
int mediaOrientation = shouldAutoRotate ? getMediaOrientation() : 0;
252+
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, mediaOrientation);
252253

253254
cameraCaptureSession.capture(
254255
captureBuilder.build(),

packages/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result)
7474
}
7575
case "takePicture":
7676
{
77-
camera.takePicture(call.argument("path"), result);
77+
camera.takePicture(call.argument("path"), call.argument("shouldAutoRotate"), result);
7878
break;
7979
}
8080
case "prepareForVideoRecording":

packages/camera/example/lib/main.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
4343
VideoPlayerController videoController;
4444
VoidCallback videoPlayerListener;
4545
bool enableAudio = true;
46+
bool enableAutoRotate = true;
4647

4748
@override
4849
void initState() {
@@ -153,6 +154,14 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
153154
}
154155
},
155156
),
157+
const Text('Enable Auto Rotate:'),
158+
Switch(
159+
value: enableAutoRotate,
160+
onChanged: (bool value) {
161+
enableAutoRotate = value;
162+
onNewCameraSelected(controller.description);
163+
},
164+
),
156165
],
157166
),
158167
);
@@ -451,7 +460,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
451460
}
452461

453462
try {
454-
await controller.takePicture(filePath);
463+
await controller.takePicture(filePath, shouldAutoRotate: enableAutoRotate);
455464
} on CameraException catch (e) {
456465
_showCameraException(e);
457466
return null;

packages/camera/ios/Classes/CameraPlugin.m

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ @interface FLTSavePhotoDelegate : NSObject <AVCapturePhotoCaptureDelegate>
1919
@property(readonly, nonatomic) FlutterResult result;
2020
@property(readonly, nonatomic) CMMotionManager *motionManager;
2121
@property(readonly, nonatomic) AVCaptureDevicePosition cameraPosition;
22+
@property(assign, nonatomic) BOOL shouldAutoRotate;
2223

2324
- initWithPath:(NSString *)filename
2425
result:(FlutterResult)result
2526
motionManager:(CMMotionManager *)motionManager
26-
cameraPosition:(AVCaptureDevicePosition)cameraPosition;
27+
cameraPosition:(AVCaptureDevicePosition)cameraPosition
28+
shouldAutoRotate:(BOOL)shouldAutoRotate;
2729
@end
2830

2931
@interface FLTImageStreamHandler : NSObject <FlutterStreamHandler>
@@ -52,13 +54,15 @@ @implementation FLTSavePhotoDelegate {
5254
- initWithPath:(NSString *)path
5355
result:(FlutterResult)result
5456
motionManager:(CMMotionManager *)motionManager
55-
cameraPosition:(AVCaptureDevicePosition)cameraPosition {
57+
cameraPosition:(AVCaptureDevicePosition)cameraPosition
58+
shouldAutoRotate:(BOOL)shouldAutoRotate {
5659
self = [super init];
5760
NSAssert(self, @"super init cannot be nil");
5861
_path = path;
5962
_result = result;
6063
_motionManager = motionManager;
6164
_cameraPosition = cameraPosition;
65+
_shouldAutoRotate = shouldAutoRotate;
6266
selfReference = self;
6367
return self;
6468
}
@@ -90,6 +94,9 @@ - (void)captureOutput:(AVCapturePhotoOutput *)output
9094
}
9195

9296
- (UIImageOrientation)getImageRotation {
97+
if (!self.shouldAutoRotate) {
98+
return UIImageOrientationRight;
99+
}
93100
float const threshold = 45.0;
94101
BOOL (^isNearValue)(float value1, float value2) = ^BOOL(float value1, float value2) {
95102
return fabsf(value1 - value2) < threshold;
@@ -204,7 +211,13 @@ - (void)startVideoRecordingAtPath:(NSString *)path result:(FlutterResult)result;
204211
- (void)stopVideoRecordingWithResult:(FlutterResult)result;
205212
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger;
206213
- (void)stopImageStream;
207-
- (void)captureToFile:(NSString *)filename result:(FlutterResult)result;
214+
/// Captures a photo and save to the specified file path.
215+
/// @param filename The path where the photo should be saved to.
216+
/// @param shouldAutoRotate Whether to automatically rotate the captured photo.
217+
/// If enabled, Saves the EXIF data according to device accelerometer.
218+
- (void)captureToFile:(NSString *)path
219+
shouldAutoRotate:(BOOL)shouldAutoRotate
220+
result:(FlutterResult)result;
208221
@end
209222

210223
@implementation FLTCam {
@@ -272,7 +285,9 @@ - (void)stop {
272285
[_captureSession stopRunning];
273286
}
274287

275-
- (void)captureToFile:(NSString *)path result:(FlutterResult)result {
288+
- (void)captureToFile:(NSString *)path
289+
shouldAutoRotate:(BOOL)shouldAutoRotate
290+
result:(FlutterResult)result {
276291
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
277292
if (_resolutionPreset == max) {
278293
[settings setHighResolutionPhotoEnabled:YES];
@@ -282,7 +297,8 @@ - (void)captureToFile:(NSString *)path result:(FlutterResult)result {
282297
delegate:[[FLTSavePhotoDelegate alloc] initWithPath:path
283298
result:result
284299
motionManager:_motionManager
285-
cameraPosition:_captureDevice.position]];
300+
cameraPosition:_captureDevice.position
301+
shouldAutoRotate:shouldAutoRotate]];
286302
}
287303

288304
- (void)setCaptureSessionPreset:(ResolutionPreset)resolutionPreset {
@@ -882,7 +898,10 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re
882898
NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue;
883899

884900
if ([@"takePicture" isEqualToString:call.method]) {
885-
[_camera captureToFile:call.arguments[@"path"] result:result];
901+
BOOL shouldAutoRotate = [call.arguments[@"shouldAutoRotate"] boolValue];
902+
[_camera captureToFile:call.arguments[@"path"]
903+
shouldAutoRotate:shouldAutoRotate
904+
result:result];
886905
} else if ([@"dispose" isEqualToString:call.method]) {
887906
[_registry unregisterTexture:textureId];
888907
[_camera close];

packages/camera/lib/camera.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ class CameraController extends ValueNotifier<CameraValue> {
339339
/// The file can be read as this function returns.
340340
///
341341
/// Throws a [CameraException] if the capture fails.
342-
Future<void> takePicture(String path) async {
342+
Future<void> takePicture(String path, {bool shouldAutoRotate = false}) async {
343343
if (!value.isInitialized || _isDisposed) {
344344
throw CameraException(
345345
'Uninitialized CameraController.',
@@ -356,7 +356,11 @@ class CameraController extends ValueNotifier<CameraValue> {
356356
value = value.copyWith(isTakingPicture: true);
357357
await _channel.invokeMethod<void>(
358358
'takePicture',
359-
<String, dynamic>{'textureId': _textureId, 'path': path},
359+
<String, dynamic>{
360+
'textureId': _textureId,
361+
'path': path,
362+
'shouldAutoRotate': shouldAutoRotate,
363+
},
360364
);
361365
value = value.copyWith(isTakingPicture: false);
362366
} on PlatformException catch (e) {

0 commit comments

Comments
 (0)