ios合并cordova camera 的取相册照片的方法
This commit is contained in:
parent
9782d52be4
commit
739cb20679
@ -126,6 +126,9 @@
|
|||||||
</feature>
|
</feature>
|
||||||
</config-file>
|
</config-file>
|
||||||
|
|
||||||
|
<header-file src="src/ios/UIImage+CropScaleOrientation.h" />
|
||||||
|
<source-file src="src/ios/UIImage+CropScaleOrientation.m" />
|
||||||
|
|
||||||
<header-file src="src/ios/classes/CustomCamera.h" />
|
<header-file src="src/ios/classes/CustomCamera.h" />
|
||||||
<source-file src="src/ios/classes/CustomCamera.m" />
|
<source-file src="src/ios/classes/CustomCamera.m" />
|
||||||
|
|
||||||
|
@ -1,4 +1,61 @@
|
|||||||
#import <Cordova/CDV.h>
|
#import <Cordova/CDV.h>
|
||||||
|
#import <CoreLocation/CoreLocation.h>
|
||||||
|
#import <CoreLocation/CLLocationManager.h>
|
||||||
|
enum CDVDestinationType {
|
||||||
|
DestinationTypeDataUrl = 0,
|
||||||
|
DestinationTypeFileUri,
|
||||||
|
DestinationTypeNativeUri
|
||||||
|
};
|
||||||
|
typedef NSUInteger CDVDestinationType;
|
||||||
|
|
||||||
|
enum CDVEncodingType {
|
||||||
|
EncodingTypeJPEG = 0,
|
||||||
|
EncodingTypePNG
|
||||||
|
};
|
||||||
|
typedef NSUInteger CDVEncodingType;
|
||||||
|
|
||||||
|
enum CDVMediaType {
|
||||||
|
MediaTypePicture = 0,
|
||||||
|
MediaTypeVideo,
|
||||||
|
MediaTypeAll
|
||||||
|
};
|
||||||
|
typedef NSUInteger CDVMediaType;
|
||||||
|
|
||||||
|
@interface CDVPictureOptions : NSObject
|
||||||
|
|
||||||
|
@property (strong) NSNumber* quality;
|
||||||
|
@property (assign) CDVDestinationType destinationType;
|
||||||
|
@property (assign) UIImagePickerControllerSourceType sourceType;
|
||||||
|
@property (assign) CGSize targetSize;
|
||||||
|
@property (assign) CDVEncodingType encodingType;
|
||||||
|
@property (assign) CDVMediaType mediaType;
|
||||||
|
@property (assign) BOOL allowsEditing;
|
||||||
|
@property (assign) BOOL correctOrientation;
|
||||||
|
@property (assign) BOOL saveToPhotoAlbum;
|
||||||
|
@property (strong) NSDictionary* popoverOptions;
|
||||||
|
@property (assign) UIImagePickerControllerCameraDevice cameraDirection;
|
||||||
|
|
||||||
|
@property (assign) BOOL popoverSupported;
|
||||||
|
@property (assign) BOOL usesGeolocation;
|
||||||
|
@property (assign) BOOL cropToSize;
|
||||||
|
|
||||||
|
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface CDVCameraPicker : UIImagePickerController
|
||||||
|
|
||||||
|
@property (strong) CDVPictureOptions* pictureOptions;
|
||||||
|
|
||||||
|
@property (copy) NSString* callbackId;
|
||||||
|
@property (copy) NSString* postUrl;
|
||||||
|
@property (strong) UIPopoverController* pickerPopoverController;
|
||||||
|
@property (assign) BOOL cropToSize;
|
||||||
|
@property (strong) UIView* webView;
|
||||||
|
|
||||||
|
+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)options;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface CustomCamera : CDVPlugin<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
|
@interface CustomCamera : CDVPlugin<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
|
||||||
{
|
{
|
||||||
@ -26,7 +83,11 @@
|
|||||||
|
|
||||||
NSString *filename;
|
NSString *filename;
|
||||||
}
|
}
|
||||||
|
@property (strong) NSData* data;
|
||||||
|
@property (strong) NSMutableDictionary *metadata;
|
||||||
|
@property (strong, nonatomic) CLLocationManager *locationManager;
|
||||||
|
@property (strong) CDVCameraPicker* pickerController;
|
||||||
- (void)startCamera:(CDVInvokedUrlCommand*)command;
|
- (void)startCamera:(CDVInvokedUrlCommand*)command;
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand*)command;
|
- (void)takePicture:(CDVInvokedUrlCommand*)command;
|
||||||
|
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions;
|
||||||
@end
|
@end
|
||||||
|
@ -1,11 +1,487 @@
|
|||||||
#import "CustomCamera.h"
|
#import "CustomCamera.h"
|
||||||
#import "AVCamViewController.h"
|
#import "AVCamViewController.h"
|
||||||
#import "CameraParameter.h"
|
#import "CameraParameter.h"
|
||||||
|
#import <MobileCoreServices/UTCoreTypes.h>
|
||||||
|
#import <AssetsLibrary/ALAssetRepresentation.h>
|
||||||
|
#import <AssetsLibrary/AssetsLibrary.h>
|
||||||
|
#import "UIImage+CropScaleOrientation.h"
|
||||||
|
#import <objc/message.h>
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
|
||||||
|
#ifndef __CORDOVA_4_0_0
|
||||||
|
#import <Cordova/NSData+Base64.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CDV_PHOTO_PREFIX @"cdv_photo_"
|
||||||
|
|
||||||
|
static NSSet* org_apache_cordova_validArrowDirections;
|
||||||
|
static NSString* toBase64(NSData* data) {
|
||||||
|
SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString");
|
||||||
|
SEL s2 = NSSelectorFromString(@"base64EncodedString");
|
||||||
|
SEL s3 = NSSelectorFromString(@"base64EncodedStringWithOptions:");
|
||||||
|
|
||||||
|
if ([data respondsToSelector:s1]) {
|
||||||
|
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1];
|
||||||
|
return func(data, s1);
|
||||||
|
} else if ([data respondsToSelector:s2]) {
|
||||||
|
NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2];
|
||||||
|
return func(data, s2);
|
||||||
|
} else if ([data respondsToSelector:s3]) {
|
||||||
|
NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3];
|
||||||
|
return func(data, s3, 0);
|
||||||
|
} else {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation CDVPictureOptions
|
||||||
|
|
||||||
|
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command
|
||||||
|
{
|
||||||
|
CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
|
||||||
|
|
||||||
|
pictureOptions.quality = [command argumentAtIndex:0 withDefault:@(50)];
|
||||||
|
pictureOptions.destinationType = [[command argumentAtIndex:1 withDefault:@(DestinationTypeFileUri)] unsignedIntegerValue];
|
||||||
|
pictureOptions.sourceType = [[command argumentAtIndex:2 withDefault:@(UIImagePickerControllerSourceTypeCamera)] unsignedIntegerValue];
|
||||||
|
|
||||||
|
NSNumber* targetWidth = [command argumentAtIndex:3 withDefault:nil];
|
||||||
|
NSNumber* targetHeight = [command argumentAtIndex:4 withDefault:nil];
|
||||||
|
pictureOptions.targetSize = CGSizeMake(0, 0);
|
||||||
|
if ((targetWidth != nil) && (targetHeight != nil)) {
|
||||||
|
pictureOptions.targetSize = CGSizeMake([targetWidth floatValue], [targetHeight floatValue]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pictureOptions.encodingType = [[command argumentAtIndex:5 withDefault:@(EncodingTypeJPEG)] unsignedIntegerValue];
|
||||||
|
pictureOptions.mediaType = [[command argumentAtIndex:6 withDefault:@(MediaTypePicture)] unsignedIntegerValue];
|
||||||
|
pictureOptions.allowsEditing = [[command argumentAtIndex:7 withDefault:@(NO)] boolValue];
|
||||||
|
pictureOptions.correctOrientation = [[command argumentAtIndex:8 withDefault:@(NO)] boolValue];
|
||||||
|
pictureOptions.saveToPhotoAlbum = [[command argumentAtIndex:9 withDefault:@(NO)] boolValue];
|
||||||
|
pictureOptions.popoverOptions = [command argumentAtIndex:10 withDefault:nil];
|
||||||
|
pictureOptions.cameraDirection = [[command argumentAtIndex:11 withDefault:@(UIImagePickerControllerCameraDeviceRear)] unsignedIntegerValue];
|
||||||
|
|
||||||
|
pictureOptions.popoverSupported = NO;
|
||||||
|
pictureOptions.usesGeolocation = NO;
|
||||||
|
|
||||||
|
return pictureOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation CDVCameraPicker
|
||||||
|
|
||||||
|
- (BOOL)prefersStatusBarHidden
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIViewController*)childViewControllerForStatusBarHidden
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated
|
||||||
|
{
|
||||||
|
SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate");
|
||||||
|
if ([self respondsToSelector:sel]) {
|
||||||
|
[self performSelector:sel withObject:nil afterDelay:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)pictureOptions;
|
||||||
|
{
|
||||||
|
CDVCameraPicker* cameraPicker = [[CDVCameraPicker alloc] init];
|
||||||
|
cameraPicker.pictureOptions = pictureOptions;
|
||||||
|
cameraPicker.sourceType = pictureOptions.sourceType;
|
||||||
|
cameraPicker.allowsEditing = pictureOptions.allowsEditing;
|
||||||
|
|
||||||
|
if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
|
||||||
|
// We only allow taking pictures (no video) in this API.
|
||||||
|
cameraPicker.mediaTypes = @[(NSString*)kUTTypeImage];
|
||||||
|
// We can only set the camera device if we're actually using the camera.
|
||||||
|
cameraPicker.cameraDevice = pictureOptions.cameraDirection;
|
||||||
|
} else if (pictureOptions.mediaType == MediaTypeAll) {
|
||||||
|
cameraPicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:cameraPicker.sourceType];
|
||||||
|
} else {
|
||||||
|
NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)];
|
||||||
|
cameraPicker.mediaTypes = mediaArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cameraPicker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface CustomCamera ()
|
||||||
|
@property (readwrite, assign) BOOL hasPendingOperation;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation CustomCamera
|
@implementation CustomCamera
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
org_apache_cordova_validArrowDirections = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:UIPopoverArrowDirectionUp], [NSNumber numberWithInt:UIPopoverArrowDirectionDown], [NSNumber numberWithInt:UIPopoverArrowDirectionLeft], [NSNumber numberWithInt:UIPopoverArrowDirectionRight], [NSNumber numberWithInt:UIPopoverArrowDirectionAny], nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
@synthesize hasPendingOperation, pickerController;
|
||||||
|
|
||||||
- (void)takePicture:(CDVInvokedUrlCommand *)command {
|
- (void)takePicture:(CDVInvokedUrlCommand *)command {
|
||||||
[self startCamera: command];
|
self.hasPendingOperation = YES;
|
||||||
|
CDVPictureOptions* pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
|
||||||
|
if (pictureOptions.sourceType == 1) {
|
||||||
|
[self startCamera: command];
|
||||||
|
} else {
|
||||||
|
[self showCameraPicker:command.callbackId withOptions:pictureOptions];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- (BOOL)popoverSupported
|
||||||
|
{
|
||||||
|
return (NSClassFromString(@"UIPopoverController") != nil) &&
|
||||||
|
(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)integerValueForKey:(NSDictionary*)dict key:(NSString*)key defaultValue:(NSInteger)defaultValue
|
||||||
|
{
|
||||||
|
NSInteger value = defaultValue;
|
||||||
|
|
||||||
|
NSNumber* val = [dict valueForKey:key]; // value is an NSNumber
|
||||||
|
|
||||||
|
if (val != nil) {
|
||||||
|
value = [val integerValue];
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)displayPopover:(NSDictionary*)options
|
||||||
|
{
|
||||||
|
NSInteger x = 0;
|
||||||
|
NSInteger y = 32;
|
||||||
|
NSInteger width = 320;
|
||||||
|
NSInteger height = 480;
|
||||||
|
UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirectionAny;
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
x = [self integerValueForKey:options key:@"x" defaultValue:0];
|
||||||
|
y = [self integerValueForKey:options key:@"y" defaultValue:32];
|
||||||
|
width = [self integerValueForKey:options key:@"width" defaultValue:320];
|
||||||
|
height = [self integerValueForKey:options key:@"height" defaultValue:480];
|
||||||
|
arrowDirection = [self integerValueForKey:options key:@"arrowDir" defaultValue:UIPopoverArrowDirectionAny];
|
||||||
|
if (![org_apache_cordova_validArrowDirections containsObject:[NSNumber numberWithUnsignedInteger:arrowDirection]]) {
|
||||||
|
arrowDirection = UIPopoverArrowDirectionAny;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[[self pickerController] pickerPopoverController] setDelegate:self];
|
||||||
|
[[[self pickerController] pickerPopoverController] presentPopoverFromRect:CGRectMake(x, y, width, height)
|
||||||
|
inView:[self.webView superview]
|
||||||
|
permittedArrowDirections:arrowDirection
|
||||||
|
animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showCameraPicker:(NSString*)callbackId withOptions:(CDVPictureOptions *) pictureOptions
|
||||||
|
{
|
||||||
|
// Perform UI operations on the main thread
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
CDVCameraPicker* cameraPicker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
|
||||||
|
self.pickerController = cameraPicker;
|
||||||
|
|
||||||
|
cameraPicker.delegate = self;
|
||||||
|
cameraPicker.callbackId = callbackId;
|
||||||
|
// we need to capture this state for memory warnings that dealloc this object
|
||||||
|
cameraPicker.webView = self.webView;
|
||||||
|
|
||||||
|
// If a popover is already open, close it; we only want one at a time.
|
||||||
|
if (([[self pickerController] pickerPopoverController] != nil) && [[[self pickerController] pickerPopoverController] isPopoverVisible]) {
|
||||||
|
[[[self pickerController] pickerPopoverController] dismissPopoverAnimated:YES];
|
||||||
|
[[[self pickerController] pickerPopoverController] setDelegate:nil];
|
||||||
|
[[self pickerController] setPickerPopoverController:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([self popoverSupported] && (pictureOptions.sourceType != UIImagePickerControllerSourceTypeCamera)) {
|
||||||
|
if (cameraPicker.pickerPopoverController == nil) {
|
||||||
|
cameraPicker.pickerPopoverController = [[NSClassFromString(@"UIPopoverController") alloc] initWithContentViewController:cameraPicker];
|
||||||
|
}
|
||||||
|
[self displayPopover:pictureOptions.popoverOptions];
|
||||||
|
self.hasPendingOperation = NO;
|
||||||
|
} else {
|
||||||
|
cameraPicker.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||||
|
[self.viewController presentViewController:cameraPicker animated:YES completion:^{
|
||||||
|
self.hasPendingOperation = NO;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options
|
||||||
|
{
|
||||||
|
// get the image
|
||||||
|
UIImage* image = nil;
|
||||||
|
if (options.allowsEditing && [info objectForKey:UIImagePickerControllerEditedImage]) {
|
||||||
|
image = [info objectForKey:UIImagePickerControllerEditedImage];
|
||||||
|
} else {
|
||||||
|
image = [info objectForKey:UIImagePickerControllerOriginalImage];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.correctOrientation) {
|
||||||
|
image = [image imageCorrectedForCaptureOrientation];
|
||||||
|
}
|
||||||
|
|
||||||
|
UIImage* scaledImage = nil;
|
||||||
|
|
||||||
|
if ((options.targetSize.width > 0) && (options.targetSize.height > 0)) {
|
||||||
|
// if cropToSize, resize image and crop to target size, otherwise resize to fit target without cropping
|
||||||
|
if (options.cropToSize) {
|
||||||
|
scaledImage = [image imageByScalingAndCroppingForSize:options.targetSize];
|
||||||
|
} else {
|
||||||
|
scaledImage = [image imageByScalingNotCroppingForSize:options.targetSize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (scaledImage == nil ? image : scaledImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSURL*) urlTransformer:(NSURL*)url
|
||||||
|
{
|
||||||
|
NSURL* urlToTransform = url;
|
||||||
|
|
||||||
|
// for backwards compatibility - we check if this property is there
|
||||||
|
SEL sel = NSSelectorFromString(@"urlTransformer");
|
||||||
|
if ([self.commandDelegate respondsToSelector:sel]) {
|
||||||
|
// grab the block from the commandDelegate
|
||||||
|
NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(self.commandDelegate, sel);
|
||||||
|
// if block is not null, we call it
|
||||||
|
if (urlTransformer) {
|
||||||
|
urlToTransform = urlTransformer(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlToTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options
|
||||||
|
{
|
||||||
|
NSData* data = nil;
|
||||||
|
|
||||||
|
switch (options.encodingType) {
|
||||||
|
case EncodingTypePNG:
|
||||||
|
data = UIImagePNGRepresentation(image);
|
||||||
|
break;
|
||||||
|
case EncodingTypeJPEG:
|
||||||
|
{
|
||||||
|
if ((options.allowsEditing == NO) && (options.targetSize.width <= 0) && (options.targetSize.height <= 0) && (options.correctOrientation == NO) && (([options.quality integerValue] == 100) || (options.sourceType != UIImagePickerControllerSourceTypeCamera))){
|
||||||
|
// use image unedited as requested , don't resize
|
||||||
|
data = UIImageJPEGRepresentation(image, 1.0);
|
||||||
|
} else {
|
||||||
|
data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.usesGeolocation) {
|
||||||
|
NSDictionary* controllerMetadata = [info objectForKey:@"UIImagePickerControllerMediaMetadata"];
|
||||||
|
if (controllerMetadata) {
|
||||||
|
self.data = data;
|
||||||
|
self.metadata = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
NSMutableDictionary* EXIFDictionary = [[controllerMetadata objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
|
||||||
|
if (EXIFDictionary) {
|
||||||
|
[self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAtLeastiOSVersion(@"8.0")) {
|
||||||
|
[[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0];
|
||||||
|
}
|
||||||
|
[[self locationManager] startUpdatingLocation];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*)tempFilePath:(NSString*)extension
|
||||||
|
{
|
||||||
|
NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath];
|
||||||
|
NSFileManager* fileMgr = [[NSFileManager alloc] init]; // recommended by Apple (vs [NSFileManager defaultManager]) to be threadsafe
|
||||||
|
NSString* filePath;
|
||||||
|
|
||||||
|
// unique file name
|
||||||
|
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
|
||||||
|
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
|
||||||
|
do {
|
||||||
|
filePath = [NSString stringWithFormat:@"%@/%@%ld.%@", docsPath, CDV_PHOTO_PREFIX, [timeStampObj longValue], extension];
|
||||||
|
} while ([fileMgr fileExistsAtPath:filePath]);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info completion:(void (^)(CDVPluginResult* res))completion
|
||||||
|
{
|
||||||
|
CDVPluginResult* result = nil;
|
||||||
|
BOOL saveToPhotoAlbum = options.saveToPhotoAlbum;
|
||||||
|
UIImage* image = nil;
|
||||||
|
|
||||||
|
switch (options.destinationType) {
|
||||||
|
case DestinationTypeNativeUri:
|
||||||
|
{
|
||||||
|
NSURL* url = [info objectForKey:UIImagePickerControllerReferenceURL];
|
||||||
|
saveToPhotoAlbum = NO;
|
||||||
|
// If, for example, we use sourceType = Camera, URL might be nil because image is stored in memory.
|
||||||
|
// In this case we must save image to device before obtaining an URI.
|
||||||
|
if (url == nil) {
|
||||||
|
image = [self retrieveImage:info options:options];
|
||||||
|
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
||||||
|
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||||
|
CDVPluginResult* resultToReturn = nil;
|
||||||
|
if (error) {
|
||||||
|
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
|
||||||
|
} else {
|
||||||
|
NSString* nativeUri = [[self urlTransformer:assetURL] absoluteString];
|
||||||
|
resultToReturn = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
||||||
|
}
|
||||||
|
completion(resultToReturn);
|
||||||
|
}];
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
NSString* nativeUri = [[self urlTransformer:url] absoluteString];
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DestinationTypeFileUri:
|
||||||
|
{
|
||||||
|
image = [self retrieveImage:info options:options];
|
||||||
|
NSData* data = [self processImage:image info:info options:options];
|
||||||
|
if (data) {
|
||||||
|
|
||||||
|
NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg";
|
||||||
|
NSString* filePath = [self tempFilePath:extension];
|
||||||
|
NSError* err = nil;
|
||||||
|
|
||||||
|
// save file
|
||||||
|
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
|
||||||
|
} else {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[[self urlTransformer:[NSURL fileURLWithPath:filePath]] absoluteString]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DestinationTypeDataUrl:
|
||||||
|
{
|
||||||
|
image = [self retrieveImage:info options:options];
|
||||||
|
NSData* data = [self processImage:image info:info options:options];
|
||||||
|
if (data) {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (saveToPhotoAlbum && image) {
|
||||||
|
ALAssetsLibrary* library = [ALAssetsLibrary new];
|
||||||
|
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) createTmpVideo:(NSString *) moviePath {
|
||||||
|
NSString* moviePathExtension = [moviePath pathExtension];
|
||||||
|
NSString* copyMoviePath = [self tempFilePath:moviePathExtension];
|
||||||
|
NSFileManager* fileMgr = [[NSFileManager alloc] init];
|
||||||
|
NSError *error;
|
||||||
|
[fileMgr copyItemAtPath:moviePath toPath:copyMoviePath error:&error];
|
||||||
|
return [[NSURL fileURLWithPath:copyMoviePath] absoluteString];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CDVPluginResult*)resultForVideo:(NSDictionary*)info
|
||||||
|
{
|
||||||
|
NSString* moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] absoluteString];
|
||||||
|
// On iOS 13 the movie path becomes inaccessible, create and return a copy
|
||||||
|
if (IsAtLeastiOSVersion(@"13.0")) {
|
||||||
|
moviePath = [self createTmpVideo:[[info objectForKey:UIImagePickerControllerMediaURL] path]];
|
||||||
|
}
|
||||||
|
return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:moviePath];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)usesGeolocation
|
||||||
|
{
|
||||||
|
id useGeo = [self.commandDelegate.settings objectForKey:[@"CameraUsesGeolocation" lowercaseString]];
|
||||||
|
return [(NSNumber*)useGeo boolValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
|
||||||
|
{
|
||||||
|
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
||||||
|
__weak CustomCamera* weakSelf = self;
|
||||||
|
|
||||||
|
dispatch_block_t invoke = ^(void) {
|
||||||
|
__block CDVPluginResult* result = nil;
|
||||||
|
|
||||||
|
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
|
||||||
|
if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
|
||||||
|
[weakSelf resultForImage:cameraPicker.pictureOptions info:info completion:^(CDVPluginResult* res) {
|
||||||
|
if (![self usesGeolocation] || picker.sourceType != UIImagePickerControllerSourceTypeCamera) {
|
||||||
|
[weakSelf.commandDelegate sendPluginResult:res callbackId:cameraPicker.callbackId];
|
||||||
|
weakSelf.hasPendingOperation = NO;
|
||||||
|
weakSelf.pickerController = nil;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = [weakSelf resultForVideo:info];
|
||||||
|
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
||||||
|
weakSelf.hasPendingOperation = NO;
|
||||||
|
weakSelf.pickerController = nil;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cameraPicker.pictureOptions.popoverSupported && (cameraPicker.pickerPopoverController != nil)) {
|
||||||
|
[cameraPicker.pickerPopoverController dismissPopoverAnimated:YES];
|
||||||
|
cameraPicker.pickerPopoverController.delegate = nil;
|
||||||
|
cameraPicker.pickerPopoverController = nil;
|
||||||
|
invoke();
|
||||||
|
} else {
|
||||||
|
[[cameraPicker presentingViewController] dismissViewControllerAnimated:YES completion:invoke];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// older api calls newer didFinishPickingMediaWithInfo
|
||||||
|
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo
|
||||||
|
{
|
||||||
|
NSDictionary* imageInfo = [NSDictionary dictionaryWithObject:image forKey:UIImagePickerControllerOriginalImage];
|
||||||
|
|
||||||
|
[self imagePickerController:picker didFinishPickingMediaWithInfo:imageInfo];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
|
||||||
|
{
|
||||||
|
__weak CDVCameraPicker* cameraPicker = (CDVCameraPicker*)picker;
|
||||||
|
__weak CustomCamera* weakSelf = self;
|
||||||
|
|
||||||
|
dispatch_block_t invoke = ^ (void) {
|
||||||
|
CDVPluginResult* result;
|
||||||
|
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera && [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] != ALAuthorizationStatusAuthorized) {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to camera"];
|
||||||
|
} else if (picker.sourceType != UIImagePickerControllerSourceTypeCamera && ! IsAtLeastiOSVersion(@"11.0") && [ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized) {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"has no access to assets"];
|
||||||
|
} else {
|
||||||
|
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No Image Selected"];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[weakSelf.commandDelegate sendPluginResult:result callbackId:cameraPicker.callbackId];
|
||||||
|
|
||||||
|
weakSelf.hasPendingOperation = NO;
|
||||||
|
weakSelf.pickerController = nil;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[cameraPicker presentingViewController] dismissViewControllerAnimated:YES completion:invoke];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startCamera:(CDVInvokedUrlCommand *)command {
|
- (void)startCamera:(CDVInvokedUrlCommand *)command {
|
||||||
@ -73,37 +549,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is called when an image has been chosen from the library or taken from the camera.
|
|
||||||
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
|
|
||||||
//You can retrieve the actual UIImage
|
|
||||||
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
|
|
||||||
//Or you can get the image url from AssetsLibrary
|
|
||||||
// NSURL *path = [info valueForKey:UIImagePickerControllerReferenceURL];
|
|
||||||
|
|
||||||
[picker dismissViewControllerAnimated:YES completion: ^{
|
|
||||||
@autoreleasepool {
|
|
||||||
if (nDestType == 0) {
|
|
||||||
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
|
|
||||||
|
|
||||||
NSString *strEncodeData = [imageData base64EncodedStringWithOptions:0];
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
||||||
messageAsString:strEncodeData];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:lastCommand.callbackId];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
|
||||||
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:filename];
|
|
||||||
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
|
|
||||||
//[self deleteFileWithName:imagePath];
|
|
||||||
[imageData writeToFile:imagePath atomically:YES];
|
|
||||||
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
|
||||||
messageAsString:[[NSURL fileURLWithPath:imagePath] absoluteString]];
|
|
||||||
[self.commandDelegate sendPluginResult:result callbackId:lastCommand.callbackId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)deleteFileWithName:(NSString *)fileName {
|
- (void)deleteFileWithName:(NSString *)fileName {
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
NSFileManager *manager = [NSFileManager defaultManager];
|
||||||
// Need to check if the to be deleted file exists.
|
// Need to check if the to be deleted file exists.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user