diff --git a/Camera.js b/Camera.js index 97e238f..12bc64c 100644 --- a/Camera.js +++ b/Camera.js @@ -82,6 +82,7 @@ export default class Camera extends Component { onBarCodeRead: PropTypes.func, onFocusChanged: PropTypes.func, onZoomChanged: PropTypes.func, + mirrorImage: PropTypes.bool, orientation: PropTypes.oneOfType([ PropTypes.string, PropTypes.number @@ -106,7 +107,8 @@ export default class Camera extends Component { captureQuality: CameraManager.CaptureQuality.high, defaultOnFocusComponent: true, flashMode: CameraManager.FlashMode.off, - torchMode: CameraManager.TorchMode.off + torchMode: CameraManager.TorchMode.off, + mirrorImage: false, }; static checkDeviceAuthorizationStatus = CameraManager.checkDeviceAuthorizationStatus; diff --git a/README.md b/README.md index d531c5a..ee7e566 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,10 @@ By default, `onZoomChanged` is not defined and pinch-to-zoom is disabled. If set to `true`, the device will not sleep while the camera preview is visible. This mimics the behavior of the default camera app, which keeps the device awake while open. +#### `iOS` `mirrorImage` + +If set to `true`, the image returned will be mirrored.. + ## Component instance methods You can access component methods by adding a `ref` (ie. `ref="camera"`) prop to your `` element, then you can use `this.refs.camera.capture(cb)`, etc. inside your component. diff --git a/ios/RCTCamera.m b/ios/RCTCamera.m index d0cf835..c7a57d6 100644 --- a/ios/RCTCamera.m +++ b/ios/RCTCamera.m @@ -68,6 +68,11 @@ } } +- (void)setMirrorImage:(BOOL)mirrorImage +{ + [self.manager changeMirrorImage:mirrorImage]; +} + - (void)setFlashMode:(NSInteger)flashMode { [self.manager changeFlashMode:flashMode]; diff --git a/ios/RCTCameraManager.h b/ios/RCTCameraManager.h index 560db5c..f96d784 100644 --- a/ios/RCTCameraManager.h +++ b/ios/RCTCameraManager.h @@ -59,6 +59,7 @@ typedef NS_ENUM(NSInteger, RCTCameraTorchMode) { @property (nonatomic, assign) NSInteger presetCamera; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; @property (nonatomic, assign) NSInteger videoTarget; +@property (nonatomic, assign) BOOL mirrorImage; @property (nonatomic, strong) RCTPromiseResolveBlock videoResolve; @property (nonatomic, strong) RCTPromiseRejectBlock videoReject; @property (nonatomic, strong) RCTCamera *camera; @@ -67,6 +68,7 @@ typedef NS_ENUM(NSInteger, RCTCameraTorchMode) { - (void)changeAspect:(NSString *)aspect; - (void)changeCamera:(NSInteger)camera; - (void)changeOrientation:(NSInteger)orientation; +- (void)changeMirrorImage:(BOOL)mirrorImage; - (void)changeFlashMode:(NSInteger)flashMode; - (void)changeTorchMode:(NSInteger)torchMode; - (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position; diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 2e6423a..ed295b8 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -31,6 +31,7 @@ RCT_EXPORT_VIEW_PROPERTY(orientation, NSInteger); RCT_EXPORT_VIEW_PROPERTY(flashMode, NSInteger); RCT_EXPORT_VIEW_PROPERTY(torchMode, NSInteger); RCT_EXPORT_VIEW_PROPERTY(keepAwake, BOOL); +RCT_EXPORT_VIEW_PROPERTY(mirrorImage, BOOL); - (NSDictionary *)constantsToExport { @@ -143,6 +144,7 @@ RCT_EXPORT_VIEW_PROPERTY(onZoomChanged, BOOL) - (id)init { if ((self = [super init])) { + self.mirrorImage = false; self.session = [AVCaptureSession new]; @@ -246,6 +248,10 @@ RCT_EXPORT_METHOD(changeOrientation:(NSInteger)orientation) { } } +RCT_EXPORT_METHOD(changeMirrorImage:(BOOL)mirrorImage) { + self.mirrorImage = mirrorImage; +} + RCT_EXPORT_METHOD(changeTorchMode:(NSInteger)torchMode) { AVCaptureDevice *device = [self.videoCaptureDeviceInput device]; NSError *error = nil; @@ -579,6 +585,12 @@ RCT_EXPORT_METHOD(hasFlash:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRej CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef bmContext = CGBitmapContextCreate(NULL, rotatedRect.size.width, rotatedRect.size.height, 8, 0, colorSpace, (CGBitmapInfo) kCGImageAlphaPremultipliedFirst); + if (self.mirrorImage) { + CGAffineTransform transform = CGAffineTransformMakeTranslation(rotatedRect.size.width, 0.0); + transform = CGAffineTransformScale(transform, -1.0, 1.0); + CGContextConcatCTM(bmContext, transform); + } + CGContextSetAllowsAntialiasing(bmContext, TRUE); CGContextSetInterpolationQuality(bmContext, kCGInterpolationNone);