[iOS] Camera support
This commit is contained in:
parent
27decf1591
commit
f1d574ca0b
|
@ -30,6 +30,20 @@ export default class App extends Component {
|
|||
};
|
||||
}
|
||||
|
||||
pickSingleWithCamera(cropping) {
|
||||
ImagePicker.openCamera({
|
||||
cropping,
|
||||
width: 500,
|
||||
height: 500
|
||||
}).then(image => {
|
||||
console.log('received image', image);
|
||||
this.setState({
|
||||
image: {uri: image.path, width: image.width, height: image.height},
|
||||
images: null
|
||||
});
|
||||
}).catch(e => alert(e));
|
||||
}
|
||||
|
||||
pickSingleBase64(cropit) {
|
||||
ImagePicker.openPicker({
|
||||
width: 300,
|
||||
|
@ -84,6 +98,12 @@ export default class App extends Component {
|
|||
{this.state.images ? this.state.images.map(i => <Image key={i.uri} style={{width: 300, height: this.scaledHeight(i.width, i.height, 300)}} source={i} />) : null}
|
||||
</ScrollView>
|
||||
|
||||
<TouchableOpacity onPress={() => this.pickSingleWithCamera(false)} style={styles.button}>
|
||||
<Text style={styles.text}>Select Single With Camera</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => this.pickSingleWithCamera(true)} style={styles.button}>
|
||||
<Text style={styles.text}>Select Single With Camera With Cropping</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => this.pickSingle(false)} style={styles.button}>
|
||||
<Text style={styles.text}>Select Single</Text>
|
||||
</TouchableOpacity>
|
||||
|
|
|
@ -400,7 +400,7 @@
|
|||
"$(inherited)",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.reactjs.native.imagecroppikcer.example;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.reactjs.native.imagecropikcer.example;
|
||||
PRODUCT_NAME = example;
|
||||
PROVISIONING_PROFILE = "";
|
||||
};
|
||||
|
@ -426,7 +426,7 @@
|
|||
"$(inherited)",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.reactjs.native.imagecroppikcer.example;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.reactjs.native.imagecropikcer.example;
|
||||
PRODUCT_NAME = example;
|
||||
PROVISIONING_PROFILE = "";
|
||||
};
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
|
||||
#import "ImageCropPicker.h"
|
||||
|
||||
#define ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_KEY @"cannot_run_camera_on_simulator"
|
||||
#define ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_MSG @"Cannot run camera on simulator"
|
||||
|
||||
#define ERROR_PICKER_NO_CAMERA_PERMISSION_KEY @"missing_camera_permission"
|
||||
#define ERROR_PICKER_NO_CAMERA_PERMISSION_MSG @"User did not grant camera permission."
|
||||
|
||||
#define ERROR_PICKER_CANCEL_KEY @"picker_cancel"
|
||||
#define ERROR_PICKER_CANCEL_MSG @"User cancelled image selection"
|
||||
|
||||
|
@ -33,9 +39,25 @@ RCT_EXPORT_MODULE();
|
|||
return self;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
- (void)checkCameraPermissions:(void(^)(BOOL granted))callback
|
||||
{
|
||||
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
||||
if (status == AVAuthorizationStatusAuthorized) {
|
||||
callback(YES);
|
||||
return;
|
||||
} else if (status == AVAuthorizationStatusNotDetermined){
|
||||
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
|
||||
callback(granted);
|
||||
return;
|
||||
}];
|
||||
} else {
|
||||
callback(NO);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setConfiguration:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject {
|
||||
|
||||
self.resolve = resolve;
|
||||
self.reject = reject;
|
||||
|
@ -43,7 +65,59 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
|||
for (NSString *key in options.keyEnumerator) {
|
||||
[self.options setValue:options[key] forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIViewController*) getRootVC {
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
while (root.presentedViewController != nil) {
|
||||
root = root.presentedViewController;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
[self setConfiguration:options resolver:resolve rejecter:reject];
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
self.reject(ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_KEY, ERROR_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR_MSG, nil);
|
||||
return;
|
||||
#else
|
||||
[self checkCameraPermissions:^(BOOL granted) {
|
||||
if (!granted) {
|
||||
self.reject(ERROR_PICKER_NO_CAMERA_PERMISSION_KEY, ERROR_PICKER_NO_CAMERA_PERMISSION_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
|
||||
picker.delegate = self;
|
||||
picker.allowsEditing = NO;
|
||||
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
||||
picker.delegate = self;
|
||||
|
||||
[[self getRootVC] presentViewController:picker animated:YES completion:nil];
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
|
||||
UIImage *chosenImage = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||
[self processSingleImagePick:chosenImage withViewController:picker];
|
||||
}
|
||||
|
||||
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
|
||||
self.reject(ERROR_PICKER_CANCEL_KEY, ERROR_PICKER_CANCEL_MSG, nil);
|
||||
[picker dismissViewControllerAnimated:YES completion:NULL];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
[self setConfiguration:options resolver:resolve rejecter:reject];
|
||||
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// init picker
|
||||
|
@ -57,11 +131,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
|||
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (root.presentedViewController) {
|
||||
[root.presentedViewController presentViewController:imagePickerController animated:YES completion:nil];
|
||||
} else {
|
||||
[root presentViewController:imagePickerController animated:YES completion:nil];
|
||||
}
|
||||
[[self getRootVC] presentViewController:imagePickerController animated:YES completion:nil];
|
||||
});
|
||||
});
|
||||
}];
|
||||
|
@ -106,52 +176,13 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
|||
self.resolve(images);
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
} else {
|
||||
PHAsset *asset = [assets objectAtIndex:0];
|
||||
|
||||
[manager
|
||||
requestImageDataForAsset:asset
|
||||
requestImageDataForAsset:[assets objectAtIndex:0]
|
||||
options:nil
|
||||
resultHandler:^(NSData *imageData, NSString *dataUTI,
|
||||
UIImageOrientation orientation,
|
||||
NSDictionary *info) {
|
||||
|
||||
if ([[[self options] objectForKey:@"cropping"] boolValue]) {
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:image cropMode:RSKImageCropModeCustom];
|
||||
|
||||
imageCropVC.avoidEmptySpaceAroundImage = YES;
|
||||
imageCropVC.dataSource = self;
|
||||
imageCropVC.delegate = self;
|
||||
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:^{
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (root.presentedViewController) {
|
||||
[root.presentedViewController presentViewController:imageCropVC animated:YES completion:nil];
|
||||
} else {
|
||||
[root presentViewController:imageCropVC animated:YES completion:nil];
|
||||
}
|
||||
});
|
||||
}];
|
||||
} else {
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
NSData *data = UIImageJPEGRepresentation(image, 1);
|
||||
NSString *filePath = [self persistFile:data];
|
||||
if (filePath == nil) {
|
||||
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
self.resolve(@{
|
||||
@"path": filePath,
|
||||
@"width": @(asset.pixelWidth),
|
||||
@"height": @(asset.pixelHeight),
|
||||
@"mime": @"image/jpeg",
|
||||
@"size": [NSNumber numberWithUnsignedInteger:data.length],
|
||||
@"data": [[self.options objectForKey:@"includeBase64"] boolValue] ? [data base64EncodedStringWithOptions:0] : [NSNull null],
|
||||
});
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
[self processSingleImagePick:[UIImage imageWithData:imageData] withViewController:imagePickerController];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +192,43 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
|||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
// when user selected single image, with camera or from photo gallery,
|
||||
// this method will take care of attaching image metadata, and sending image to cropping controller
|
||||
// or to user directly
|
||||
- (void) processSingleImagePick:(UIImage*)image withViewController:(UIViewController*)viewController {
|
||||
if ([[[self options] objectForKey:@"cropping"] boolValue]) {
|
||||
RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:image cropMode:RSKImageCropModeCustom];
|
||||
|
||||
imageCropVC.avoidEmptySpaceAroundImage = YES;
|
||||
imageCropVC.dataSource = self;
|
||||
imageCropVC.delegate = self;
|
||||
|
||||
[viewController dismissViewControllerAnimated:YES completion:^{
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[self getRootVC] presentViewController:imageCropVC animated:YES completion:nil];
|
||||
});
|
||||
}];
|
||||
} else {
|
||||
NSData *data = UIImageJPEGRepresentation(image, 1);
|
||||
NSString *filePath = [self persistFile:data];
|
||||
if (filePath == nil) {
|
||||
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
self.resolve(@{
|
||||
@"path": filePath,
|
||||
@"width": @(image.size.width),
|
||||
@"height": @(image.size.height),
|
||||
@"mime": @"image/jpeg",
|
||||
@"size": [NSNumber numberWithUnsignedInteger:data.length],
|
||||
@"data": [[self.options objectForKey:@"includeBase64"] boolValue] ? [data base64EncodedStringWithOptions:0] : [NSNull null],
|
||||
});
|
||||
[viewController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - CustomCropModeDelegates
|
||||
|
||||
// Returns a custom rect for the mask.
|
||||
|
|
Loading…
Reference in New Issue