From 007068555ef1d9e7a95fe4c679ab3fee82524e8a Mon Sep 17 00:00:00 2001 From: Ivan Pusic Date: Wed, 8 Feb 2017 12:28:48 +0100 Subject: [PATCH] (ios/android) cropping only improvements --- .../ivpusic/imagepicker/PickerModule.java | 7 ++--- example/android/build.gradle | 2 +- example/app.js | 26 ++++++++++++++++++- ios/ImageCropPicker.h | 6 ++--- ios/ImageCropPicker.m | 25 +++++++++--------- ios/imageCropPicker.xcodeproj/project.pbxproj | 20 ++++++++------ package.json | 2 +- 7 files changed, 58 insertions(+), 30 deletions(-) diff --git a/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java b/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java index 9649da3..967bc8c 100644 --- a/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java +++ b/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java @@ -345,10 +345,11 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist"); return; } - Uri uri = Uri.parse(options.getString("path")); - resultCollector = new ResultCollector(promise, multiple); setConfiguration(options); + resultCollector = new ResultCollector(promise, false); + + Uri uri = Uri.parse(options.getString("path")); startCropping(activity, uri); } @@ -534,12 +535,12 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi //If they pass a custom tint color in, we use this for everything options.setActiveWidgetColor(color); } - } private void startCropping(Activity activity, Uri uri) { UCrop.Options options = new UCrop.Options(); options.setCompressionFormat(Bitmap.CompressFormat.JPEG); + options.setCompressionQuality(100); options.setCircleDimmedLayer(cropperCircleOverlay); configureCropperColors(options); diff --git a/example/android/build.gradle b/example/android/build.gradle index f3bd7d3..eed9972 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.2' + classpath 'com.android.tools.build:gradle:2.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/example/app.js b/example/app.js index ee0a357..5cbfdc8 100644 --- a/example/app.js +++ b/example/app.js @@ -56,7 +56,7 @@ export default class App extends Component { cropping: cropit, includeBase64: true }).then(image => { - console.log('received image', image); + console.log('received base64 image'); this.setState({ image: {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height}, images: null @@ -83,6 +83,27 @@ export default class App extends Component { }) } + cropLast() { + if (!this.state.image) { + return Alert.alert('No image', 'Before open cropping only, please select image'); + } + + ImagePicker.openCropper({ + path: this.state.image.uri, + width: 200, + height: 200 + }).then(image => { + console.log('received cropped image', image); + this.setState({ + image: {uri: image.path, width: image.width, height: image.height, mime: image.mime}, + images: null + }); + }).catch(e => { + console.log(e); + Alert.alert(e.message ? e.message : e); + }); + } + pickSingle(cropit, circular=false) { ImagePicker.openPicker({ width: 300, @@ -171,6 +192,9 @@ export default class App extends Component { this.pickSingle(false)} style={styles.button}> Select Single + this.cropLast()} style={styles.button}> + Crop Last Selected Image + this.pickSingleBase64(false)} style={styles.button}> Select Single Returning Base64 diff --git a/ios/ImageCropPicker.h b/ios/ImageCropPicker.h index 1dada1d..8332c07 100644 --- a/ios/ImageCropPicker.h +++ b/ios/ImageCropPicker.h @@ -9,15 +9,15 @@ #define RN_IMAGE_CROP_PICKER_h #import + #if __has_include("RCTBridgeModule.h") #import "RCTBridgeModule.h" -#import "RCTLog.h" #import "RCTImageLoader.h" #else #import -#import #import #endif + #import "QBImagePicker/QBImagePicker.h" #import "RSKImageCropper/RSKImageCropper.h" #import "UIImage-Resize/UIImage+Resize.h" @@ -39,4 +39,4 @@ @end -#endif \ No newline at end of file +#endif diff --git a/ios/ImageCropPicker.m b/ios/ImageCropPicker.m index 1600d46..56191d9 100644 --- a/ios/ImageCropPicker.m +++ b/ios/ImageCropPicker.m @@ -108,7 +108,7 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options rejecter:(RCTPromiseRejectBlock)reject) { [self setConfiguration:options resolver:resolve rejecter:reject]; - self.cropOnly = false; + self.cropOnly = NO; #if TARGET_IPHONE_SIMULATOR self.reject(ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_KEY, ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_MSG, nil); @@ -201,7 +201,8 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options rejecter:(RCTPromiseRejectBlock)reject) { [self setConfiguration:options resolver:resolve rejecter:reject]; - self.cropOnly = false; + self.cropOnly = NO; + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status != PHAuthorizationStatusAuthorized) { self.reject(ERROR_PICKER_UNAUTHORIZED_KEY, ERROR_PICKER_UNAUTHORIZED_MSG, nil); @@ -250,13 +251,12 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options rejecter:(RCTPromiseRejectBlock)reject) { [self setConfiguration:options resolver:resolve rejecter:reject]; - self.cropOnly = true; + self.cropOnly = YES; NSString *path = [options objectForKey:@"path"]; NSURL *url = [NSURL URLWithString:path]; - NSURLRequest *imageUrlrequest = [NSURLRequest requestWithURL:url]; - [self.bridge.imageLoader loadImageWithURLRequest:imageUrlrequest callback:^(NSError *error, UIImage *image) { + [self.bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:path] callback:^(NSError *error, UIImage *image) { if (error) { self.reject(ERROR_CROPPER_IMAGE_NOT_FOUND_KEY, ERROR_CROPPER_IMAGE_NOT_FOUND_MSG, nil); } else { @@ -590,10 +590,13 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options - (void)imageCropViewControllerDidCancelCrop: (RSKImageCropViewController *)controller { self.reject(ERROR_PICKER_CANCEL_KEY, ERROR_PICKER_CANCEL_MSG, nil); + [self dismissCropper:controller]; +} +- (void) dismissCropper:(RSKImageCropViewController*) controller { //We've presented the cropper on top of the image picker as to not have a double modal animation. //Thus, we need to dismiss the image picker view controller to dismiss the whole stack. - if (self.cropOnly == false) { + if (!self.cropOnly) { UIViewController *topViewController = controller.presentingViewController.presentingViewController; [topViewController dismissViewControllerAnimated:YES completion:nil]; } else { @@ -612,14 +615,10 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options UIImage *resizedImage = [croppedImage resizedImageToFitInSize:resizedImageSize scaleIfSmaller:YES]; ImageResult *imageResult = [self.compression compressImage:resizedImage withOptions:self.options]; - //We've presented the cropper on top of the image picker as to not have a double modal animation. - //Thus, we need to dismiss the image picker view controller to dismiss the whole stack. - UIViewController *topViewController = controller.presentingViewController.presentingViewController; - NSString *filePath = [self persistFile:imageResult.data]; if (filePath == nil) { self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil); - [topViewController dismissViewControllerAnimated:YES completion:nil]; + [self dismissCropper:controller]; return; } @@ -630,7 +629,7 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options withSize:[NSNumber numberWithUnsignedInteger:imageResult.data.length] withData:[[self.options objectForKey:@"includeBase64"] boolValue] ? [imageResult.data base64EncodedStringWithOptions:0] : [NSNull null]]); - [topViewController dismissViewControllerAnimated:YES completion:nil]; + [self dismissCropper:controller]; } // at the moment it is not possible to upload image by reading PHAsset @@ -659,4 +658,4 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options [self imageCropViewController:controller didCropImage:croppedImage usingCropRect:cropRect]; } -@end \ No newline at end of file +@end diff --git a/ios/imageCropPicker.xcodeproj/project.pbxproj b/ios/imageCropPicker.xcodeproj/project.pbxproj index 3d5f292..85f4d93 100644 --- a/ios/imageCropPicker.xcodeproj/project.pbxproj +++ b/ios/imageCropPicker.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 3408F5F01E0DE76F00E97159 /* Compression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Compression.m; sourceTree = ""; }; 34434E261D6F5EA300BF5063 /* QBImagePicker.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QBImagePicker.xcodeproj; path = QBImagePicker/QBImagePicker.xcodeproj; sourceTree = ""; }; 34434E351D6F5EBB00BF5063 /* RSKImageCropper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSKImageCropper.xcodeproj; path = RSKImageCropper/RSKImageCropper.xcodeproj; sourceTree = ""; }; + 347ACA051E4B2B2F0068D500 /* libRCTImage.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libRCTImage.a; path = "../../../../Library/Developer/Xcode/DerivedData/example-grvsvunjwoajzcfynrlckgmefufr/Build/Products/Debug-iphonesimulator/libRCTImage.a"; sourceTree = ""; }; 34963A931D6B919800F9CA2F /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Resize.h"; path = "UIImage-Resize/UIImage+Resize.h"; sourceTree = ""; }; 34963A941D6B919800F9CA2F /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Resize.m"; path = "UIImage-Resize/UIImage+Resize.m"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -69,6 +70,7 @@ 34963A931D6B919800F9CA2F /* UIImage+Resize.h */, 34963A941D6B919800F9CA2F /* UIImage+Resize.m */, 3400A8091CEB54A6008A0BC7 /* Products */, + 347ACA041E4B2B2F0068D500 /* Frameworks */, ); sourceTree = ""; }; @@ -105,6 +107,14 @@ name = Products; sourceTree = ""; }; + 347ACA041E4B2B2F0068D500 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 347ACA051E4B2B2F0068D500 /* libRCTImage.a */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -293,10 +303,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../example/node_modules/react-native/React/**", - "$(SRCROOT)/../../react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/QBImagePicker/**/**", - "$(SRCROOT)/../../react-native/Libraries/Image/**", + "$(SRCROOT)/../example/node_modules/react-native/Libraries/Image/**", ); LD_RUNPATH_SEARCH_PATHS = ""; ONLY_ACTIVE_ARCH = NO; @@ -317,10 +324,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/../example/node_modules/react-native/React/**", - "$(SRCROOT)/../../react-native/React/**", - "$(SRCROOT)/../node_modules/react-native/React/**", - "$(SRCROOT)/QBImagePicker/**/**", - "$(SRCROOT)/../../react-native/Libraries/Image/**", + "$(SRCROOT)/../example/node_modules/react-native/Libraries/Image/**", ); LD_RUNPATH_SEARCH_PATHS = ""; OTHER_LDFLAGS = ( diff --git a/package.json b/package.json index 8dcd46c..7148320 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-image-crop-picker", - "version": "0.12.2", + "version": "0.12.3", "description": "Select single or multiple images, with croping option", "main": "index.js", "scripts": {