(ios/android) cropping only improvements

This commit is contained in:
Ivan Pusic 2017-02-08 12:28:48 +01:00
parent af3ed8a4d1
commit 007068555e
7 changed files with 58 additions and 30 deletions

View File

@ -345,10 +345,11 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist"); promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist");
return; return;
} }
Uri uri = Uri.parse(options.getString("path"));
resultCollector = new ResultCollector(promise, multiple);
setConfiguration(options); setConfiguration(options);
resultCollector = new ResultCollector(promise, false);
Uri uri = Uri.parse(options.getString("path"));
startCropping(activity, uri); 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 //If they pass a custom tint color in, we use this for everything
options.setActiveWidgetColor(color); options.setActiveWidgetColor(color);
} }
} }
private void startCropping(Activity activity, Uri uri) { private void startCropping(Activity activity, Uri uri) {
UCrop.Options options = new UCrop.Options(); UCrop.Options options = new UCrop.Options();
options.setCompressionFormat(Bitmap.CompressFormat.JPEG); options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
options.setCompressionQuality(100);
options.setCircleDimmedLayer(cropperCircleOverlay); options.setCircleDimmedLayer(cropperCircleOverlay);
configureCropperColors(options); configureCropperColors(options);

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { 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 // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@ -56,7 +56,7 @@ export default class App extends Component {
cropping: cropit, cropping: cropit,
includeBase64: true includeBase64: true
}).then(image => { }).then(image => {
console.log('received image', image); console.log('received base64 image');
this.setState({ this.setState({
image: {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height}, image: {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height},
images: null 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) { pickSingle(cropit, circular=false) {
ImagePicker.openPicker({ ImagePicker.openPicker({
width: 300, width: 300,
@ -171,6 +192,9 @@ export default class App extends Component {
<TouchableOpacity onPress={() => this.pickSingle(false)} style={styles.button}> <TouchableOpacity onPress={() => this.pickSingle(false)} style={styles.button}>
<Text style={styles.text}>Select Single</Text> <Text style={styles.text}>Select Single</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity onPress={() => this.cropLast()} style={styles.button}>
<Text style={styles.text}>Crop Last Selected Image</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.pickSingleBase64(false)} style={styles.button}> <TouchableOpacity onPress={() => this.pickSingleBase64(false)} style={styles.button}>
<Text style={styles.text}>Select Single Returning Base64</Text> <Text style={styles.text}>Select Single Returning Base64</Text>
</TouchableOpacity> </TouchableOpacity>

View File

@ -9,15 +9,15 @@
#define RN_IMAGE_CROP_PICKER_h #define RN_IMAGE_CROP_PICKER_h
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#if __has_include("RCTBridgeModule.h") #if __has_include("RCTBridgeModule.h")
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"
#import "RCTLog.h"
#import "RCTImageLoader.h" #import "RCTImageLoader.h"
#else #else
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import <React/RCTImageLoader.h> #import <React/RCTImageLoader.h>
#endif #endif
#import "QBImagePicker/QBImagePicker.h" #import "QBImagePicker/QBImagePicker.h"
#import "RSKImageCropper/RSKImageCropper.h" #import "RSKImageCropper/RSKImageCropper.h"
#import "UIImage-Resize/UIImage+Resize.h" #import "UIImage-Resize/UIImage+Resize.h"
@ -39,4 +39,4 @@
@end @end
#endif #endif

View File

@ -108,7 +108,7 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options
rejecter:(RCTPromiseRejectBlock)reject) { rejecter:(RCTPromiseRejectBlock)reject) {
[self setConfiguration:options resolver:resolve rejecter:reject]; [self setConfiguration:options resolver:resolve rejecter:reject];
self.cropOnly = false; self.cropOnly = NO;
#if TARGET_IPHONE_SIMULATOR #if TARGET_IPHONE_SIMULATOR
self.reject(ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_KEY, ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_MSG, nil); 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) { rejecter:(RCTPromiseRejectBlock)reject) {
[self setConfiguration:options resolver:resolve rejecter:reject]; [self setConfiguration:options resolver:resolve rejecter:reject];
self.cropOnly = false; self.cropOnly = NO;
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status != PHAuthorizationStatusAuthorized) { if (status != PHAuthorizationStatusAuthorized) {
self.reject(ERROR_PICKER_UNAUTHORIZED_KEY, ERROR_PICKER_UNAUTHORIZED_MSG, nil); self.reject(ERROR_PICKER_UNAUTHORIZED_KEY, ERROR_PICKER_UNAUTHORIZED_MSG, nil);
@ -250,13 +251,12 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options
rejecter:(RCTPromiseRejectBlock)reject) { rejecter:(RCTPromiseRejectBlock)reject) {
[self setConfiguration:options resolver:resolve rejecter:reject]; [self setConfiguration:options resolver:resolve rejecter:reject];
self.cropOnly = true; self.cropOnly = YES;
NSString *path = [options objectForKey:@"path"]; NSString *path = [options objectForKey:@"path"];
NSURL *url = [NSURL URLWithString:path]; NSURL *url = [NSURL URLWithString:path];
NSURLRequest *imageUrlrequest = [NSURLRequest requestWithURL:url]; [self.bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:path] callback:^(NSError *error, UIImage *image) {
[self.bridge.imageLoader loadImageWithURLRequest:imageUrlrequest callback:^(NSError *error, UIImage *image) {
if (error) { if (error) {
self.reject(ERROR_CROPPER_IMAGE_NOT_FOUND_KEY, ERROR_CROPPER_IMAGE_NOT_FOUND_MSG, nil); self.reject(ERROR_CROPPER_IMAGE_NOT_FOUND_KEY, ERROR_CROPPER_IMAGE_NOT_FOUND_MSG, nil);
} else { } else {
@ -590,10 +590,13 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options
- (void)imageCropViewControllerDidCancelCrop: - (void)imageCropViewControllerDidCancelCrop:
(RSKImageCropViewController *)controller { (RSKImageCropViewController *)controller {
self.reject(ERROR_PICKER_CANCEL_KEY, ERROR_PICKER_CANCEL_MSG, nil); 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. //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. //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; UIViewController *topViewController = controller.presentingViewController.presentingViewController;
[topViewController dismissViewControllerAnimated:YES completion:nil]; [topViewController dismissViewControllerAnimated:YES completion:nil];
} else { } else {
@ -612,14 +615,10 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options
UIImage *resizedImage = [croppedImage resizedImageToFitInSize:resizedImageSize scaleIfSmaller:YES]; UIImage *resizedImage = [croppedImage resizedImageToFitInSize:resizedImageSize scaleIfSmaller:YES];
ImageResult *imageResult = [self.compression compressImage:resizedImage withOptions:self.options]; 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]; NSString *filePath = [self persistFile:imageResult.data];
if (filePath == nil) { if (filePath == nil) {
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil); self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
[topViewController dismissViewControllerAnimated:YES completion:nil]; [self dismissCropper:controller];
return; return;
} }
@ -630,7 +629,7 @@ RCT_EXPORT_METHOD(openCropper:(NSDictionary *)options
withSize:[NSNumber numberWithUnsignedInteger:imageResult.data.length] withSize:[NSNumber numberWithUnsignedInteger:imageResult.data.length]
withData:[[self.options objectForKey:@"includeBase64"] boolValue] ? [imageResult.data base64EncodedStringWithOptions:0] : [NSNull null]]); 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 // 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]; [self imageCropViewController:controller didCropImage:croppedImage usingCropRect:cropRect];
} }
@end @end

View File

@ -41,6 +41,7 @@
3408F5F01E0DE76F00E97159 /* Compression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Compression.m; sourceTree = "<group>"; }; 3408F5F01E0DE76F00E97159 /* Compression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Compression.m; sourceTree = "<group>"; };
34434E261D6F5EA300BF5063 /* QBImagePicker.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QBImagePicker.xcodeproj; path = QBImagePicker/QBImagePicker.xcodeproj; sourceTree = "<group>"; }; 34434E261D6F5EA300BF5063 /* QBImagePicker.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QBImagePicker.xcodeproj; path = QBImagePicker/QBImagePicker.xcodeproj; sourceTree = "<group>"; };
34434E351D6F5EBB00BF5063 /* RSKImageCropper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSKImageCropper.xcodeproj; path = RSKImageCropper/RSKImageCropper.xcodeproj; sourceTree = "<group>"; }; 34434E351D6F5EBB00BF5063 /* RSKImageCropper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSKImageCropper.xcodeproj; path = RSKImageCropper/RSKImageCropper.xcodeproj; sourceTree = "<group>"; };
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 = "<group>"; };
34963A931D6B919800F9CA2F /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Resize.h"; path = "UIImage-Resize/UIImage+Resize.h"; sourceTree = "<group>"; }; 34963A931D6B919800F9CA2F /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Resize.h"; path = "UIImage-Resize/UIImage+Resize.h"; sourceTree = "<group>"; };
34963A941D6B919800F9CA2F /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Resize.m"; path = "UIImage-Resize/UIImage+Resize.m"; sourceTree = "<group>"; }; 34963A941D6B919800F9CA2F /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Resize.m"; path = "UIImage-Resize/UIImage+Resize.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -69,6 +70,7 @@
34963A931D6B919800F9CA2F /* UIImage+Resize.h */, 34963A931D6B919800F9CA2F /* UIImage+Resize.h */,
34963A941D6B919800F9CA2F /* UIImage+Resize.m */, 34963A941D6B919800F9CA2F /* UIImage+Resize.m */,
3400A8091CEB54A6008A0BC7 /* Products */, 3400A8091CEB54A6008A0BC7 /* Products */,
347ACA041E4B2B2F0068D500 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -105,6 +107,14 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
347ACA041E4B2B2F0068D500 /* Frameworks */ = {
isa = PBXGroup;
children = (
347ACA051E4B2B2F0068D500 /* libRCTImage.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -293,10 +303,7 @@
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(SRCROOT)/../example/node_modules/react-native/React/**", "$(SRCROOT)/../example/node_modules/react-native/React/**",
"$(SRCROOT)/../../react-native/React/**", "$(SRCROOT)/../example/node_modules/react-native/Libraries/Image/**",
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/QBImagePicker/**/**",
"$(SRCROOT)/../../react-native/Libraries/Image/**",
); );
LD_RUNPATH_SEARCH_PATHS = ""; LD_RUNPATH_SEARCH_PATHS = "";
ONLY_ACTIVE_ARCH = NO; ONLY_ACTIVE_ARCH = NO;
@ -317,10 +324,7 @@
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(SRCROOT)/../example/node_modules/react-native/React/**", "$(SRCROOT)/../example/node_modules/react-native/React/**",
"$(SRCROOT)/../../react-native/React/**", "$(SRCROOT)/../example/node_modules/react-native/Libraries/Image/**",
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/QBImagePicker/**/**",
"$(SRCROOT)/../../react-native/Libraries/Image/**",
); );
LD_RUNPATH_SEARCH_PATHS = ""; LD_RUNPATH_SEARCH_PATHS = "";
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (

View File

@ -1,6 +1,6 @@
{ {
"name": "react-native-image-crop-picker", "name": "react-native-image-crop-picker",
"version": "0.12.2", "version": "0.12.3",
"description": "Select single or multiple images, with croping option", "description": "Select single or multiple images, with croping option",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {