From cf44ac00cc498effbcfb31b7ea62dc93e9ab0694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Villeneuve?= Date: Mon, 21 Aug 2017 10:00:39 +0200 Subject: [PATCH] Allow plugging with custom-crop, improvements --- README.md | 13 +++++++++-- ios/DocumentScannerView.h | 8 ------- ios/DocumentScannerView.m | 40 +++++++++++++++++++++++----------- ios/IPDFCameraViewController.h | 2 +- ios/IPDFCameraViewController.m | 21 ++++++++++-------- package.json | 2 +- 6 files changed, 52 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index d622d20..a38c849 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ Features : - Flash - Easy to use base64 image + #### Can be easily plugged with [react-native-custom-crop](https://github.com/Michaelvilleneuve/react-native-custom-crop) + + + ![Demo crop gif](https://camo.githubusercontent.com/0ac887deaa7263172a5fd2759dba3d692e98585a/68747470733a2f2f73332d65752d776573742d312e616d617a6f6e6177732e636f6d2f6d69636861656c76696c6c656e657576652f64656d6f2d63726f702e676966) + ## Getting started `$ npm install react-native-document-scanner --save` @@ -34,7 +39,11 @@ class YourComponent extends Component { return ( this.setState({ image: data.image })} + onPictureTaken={data => this.setState({ + image: data.image, + initialImage: data.initialImage, + rectangleCoordinates: data.rectangleCoordinates, + })} overlayColor="rgba(255,130,0, 0.7)" enableTorch={false} brightness={0.3} @@ -89,7 +98,7 @@ Enum (0, 1 or 2) corresponding to the type of rectangle found | Prop | Params | Type | Description | | :----------- |:-------:| :--------:| :----------| -| onPictureTaken | `data` | `object` | Returns the captured image in an object `{ image: 'BASE64 string'}` | +| onPictureTaken | `data` | `object` | Returns the captured image in an object `{ image: 'BASE64 string', initialImage: 'BASE64 string', rectangleCoordinates: 'object of coordinates' }` | diff --git a/ios/DocumentScannerView.h b/ios/DocumentScannerView.h index fbea2ca..6944575 100644 --- a/ios/DocumentScannerView.h +++ b/ios/DocumentScannerView.h @@ -1,11 +1,3 @@ -// -// DocumentScannerView.h -// DocumentScanner -// -// Created by Marc PEYSALE on 22/06/2017. -// Copyright © 2017 Snapp'. All rights reserved. -// - #import "IPDFCameraViewController.h" #import diff --git a/ios/DocumentScannerView.m b/ios/DocumentScannerView.m index fda59da..978050b 100644 --- a/ios/DocumentScannerView.m +++ b/ios/DocumentScannerView.m @@ -1,11 +1,3 @@ -// -// DocumentScannerView.m -// DocumentScanner -// -// Created by Marc PEYSALE on 22/06/2017. -// Copyright © 2017 Snapp'. All rights reserved. -// - #import "DocumentScannerView.h" #import "IPDFCameraViewController.h" @@ -25,8 +17,6 @@ - (instancetype)init { [self setBrightness: self.brightness]; [self setSaturation: self.saturation]; - NSLog(@"detectionCountBeforeCapture: %ld", (long)self.detectionCountBeforeCapture); - NSLog(@"detectionRefreshRateInMS: %ld", (long)self.detectionRefreshRateInMS); [self start]; [self setDelegate: self]; @@ -50,10 +40,34 @@ - (void) didDetectRectangle:(CIRectangleFeature *)rectangle withType:(IPDFRectan } if (self.stableCounter > self.detectionCountBeforeCapture){ - [self captureImageWithCompletionHander:^(id data) { + [self captureImageWithCompletionHander:^(UIImage *croppedImage, UIImage *initialImage, CIRectangleFeature *rectangleFeature) { if (self.onPictureTaken) { - NSData *imageData = UIImageJPEGRepresentation(data, self.quality); - self.onPictureTaken(@{@"image": [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]}); + NSData *croppedImageData = UIImageJPEGRepresentation(croppedImage, self.quality); + + if (initialImage.imageOrientation != UIImageOrientationUp) { + UIGraphicsBeginImageContextWithOptions(initialImage.size, false, initialImage.scale); + [initialImage drawInRect:CGRectMake(0, 0, initialImage.size.width + , initialImage.size.height)]; + initialImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + } + NSData *initialImageData = UIImageJPEGRepresentation(initialImage, self.quality); + + /* + RectangleCoordinates expects a rectanle viewed from portrait, + while rectangleFeature returns a rectangle viewed from landscape, which explains the nonsense of the mapping below. + Sorry about that. + */ + self.onPictureTaken(@{ + @"croppedImage": [croppedImageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength], + @"initialImage": [initialImageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength], + @"rectangleCoordinates": @{ + @"topLeft": @{ @"y": @(rectangleFeature.bottomLeft.x + 30), @"x": @(rectangleFeature.bottomLeft.y)}, + @"topRight": @{ @"y": @(rectangleFeature.topLeft.x + 30), @"x": @(rectangleFeature.topLeft.y)}, + @"bottomLeft": @{ @"y": @(rectangleFeature.bottomRight.x), @"x": @(rectangleFeature.bottomRight.y)}, + @"bottomRight": @{ @"y": @(rectangleFeature.topRight.x), @"x": @(rectangleFeature.topRight.y)}, + } + }); [self stop]; } }]; diff --git a/ios/IPDFCameraViewController.h b/ios/IPDFCameraViewController.h index 2ef3529..3519971 100644 --- a/ios/IPDFCameraViewController.h +++ b/ios/IPDFCameraViewController.h @@ -43,7 +43,7 @@ typedef NS_ENUM(NSInteger, IPDFRectangeType) - (void)focusAtPoint:(CGPoint)point completionHandler:(void(^)())completionHandler; -- (void)captureImageWithCompletionHander:(void(^)(id data))completionHandler; +- (void)captureImageWithCompletionHander:(void(^)(UIImage *data, UIImage *initialData, CIRectangleFeature *rectangleFeature))completionHandler; @property (nonatomic, strong) UIColor* overlayColor; @property (nonatomic, assign) float saturation; diff --git a/ios/IPDFCameraViewController.m b/ios/IPDFCameraViewController.m index e2ca8e2..a30d0fd 100644 --- a/ios/IPDFCameraViewController.m +++ b/ios/IPDFCameraViewController.m @@ -323,7 +323,7 @@ - (void)focusAtPoint:(CGPoint)point completionHandler:(void(^)())completionHandl } } -- (void)captureImageWithCompletionHander:(void(^)(id data))completionHandler +- (void)captureImageWithCompletionHander:(void(^)(id data, id initialData, CIRectangleFeature *rectangleFeature))completionHandler { if (_isCapturing) return; @@ -377,21 +377,24 @@ - (void)captureImageWithCompletionHander:(void(^)(id data))completionHandler if (rectangleFeature) { enhancedImage = [self correctPerspectiveForImage:enhancedImage withFeatures:rectangleFeature]; + + UIGraphicsBeginImageContext(CGSizeMake(enhancedImage.extent.size.height, enhancedImage.extent.size.width)); + [[UIImage imageWithCIImage:enhancedImage scale:1.0 orientation:UIImageOrientationRight] drawInRect:CGRectMake(0,0, enhancedImage.extent.size.height, enhancedImage.extent.size.width)]; + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIImage *initialImage = [UIImage imageWithData:imageData]; + UIGraphicsEndImageContext(); + + [weakSelf hideGLKView:NO completion:nil]; + completionHandler(image, initialImage, rectangleFeature); } } - UIGraphicsBeginImageContext(CGSizeMake(enhancedImage.extent.size.height, enhancedImage.extent.size.width)); - [[UIImage imageWithCIImage:enhancedImage scale:1.0 orientation:UIImageOrientationRight] drawInRect:CGRectMake(0,0, enhancedImage.extent.size.height, enhancedImage.extent.size.width)]; - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - [weakSelf hideGLKView:NO completion:nil]; - completionHandler(image); } else { [weakSelf hideGLKView:NO completion:nil]; - completionHandler(imageData); + UIImage *initialImage = [UIImage imageWithData:imageData]; + completionHandler(initialImage, initialImage, nil); } _isCapturing = NO; diff --git a/package.json b/package.json index ac0b209..ac2dcfc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ { "name": "react-native-document-scanner", "description": "Scan documents, automatic border detection, automatic crop", - "version": "1.1.2", + "version": "1.2.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1"