From 8eafce0cf813b9b3e267fb45824a2c13adfa7a89 Mon Sep 17 00:00:00 2001 From: Alpesh Date: Thu, 25 Jan 2018 19:13:34 +0530 Subject: [PATCH 1/4] Camera plugin issue for corrupted image iOS --- src/ios/CDVCamera.m | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ios/CDVCamera.m b/src/ios/CDVCamera.m index 37b4ec845..7b57e0ba7 100644 --- a/src/ios/CDVCamera.m +++ b/src/ios/CDVCamera.m @@ -29,6 +29,7 @@ Licensed to the Apache Software Foundation (ASF) under one #import #import #import +#import #ifndef __CORDOVA_4_0_0 #import @@ -360,7 +361,22 @@ - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic { 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); + if(options.sourceType != UIImagePickerControllerSourceTypeCamera){ + NSURL *url = info[UIImagePickerControllerReferenceURL]; + PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil]; + PHAsset *asset = [result firstObject]; + if (asset) { + PHImageManager *manager = [PHImageManager defaultManager]; + PHImageRequestOptions *option = [PHImageRequestOptions alloc]; + option.synchronous = true; + [manager requestImageDataForAsset:asset options:option resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { + data = imageData; + }]; + } + } + else{ + return data = UIImageJPEGRepresentation(image, 1.0); + } } else { data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f); } From e81b825c1c8ecdb2706e3e34c9ee5dc072b22316 Mon Sep 17 00:00:00 2001 From: Alpesh Patel Date: Fri, 26 Jan 2018 14:44:01 +0530 Subject: [PATCH 2/4] Chaged block return statement --- src/ios/CDVCamera.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ios/CDVCamera.m b/src/ios/CDVCamera.m index 7b57e0ba7..61285eb06 100644 --- a/src/ios/CDVCamera.m +++ b/src/ios/CDVCamera.m @@ -351,7 +351,7 @@ - (void)popoverControllerDidDismissPopover:(id)popoverController - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options { - NSData* data = nil; + __block NSData* data = nil; switch (options.encodingType) { case EncodingTypePNG: From 2048c0c4e5ad86f601cc961f909059a00e0d04d1 Mon Sep 17 00:00:00 2001 From: Alpesh Date: Fri, 26 Jan 2018 18:53:49 +0530 Subject: [PATCH 3/4] Added async image processing as author suggest --- src/ios/CDVCamera.m | 114 +++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/src/ios/CDVCamera.m b/src/ios/CDVCamera.m index 61285eb06..ebf571d38 100644 --- a/src/ios/CDVCamera.m +++ b/src/ios/CDVCamera.m @@ -348,50 +348,54 @@ - (void)popoverControllerDidDismissPopover:(id)popoverController } self.hasPendingOperation = NO; } - -- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options -{ +typedef void(^successBlock)(NSData *); +-(void) newProcessImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options block:(successBlock)success { __block NSData* data = nil; - + switch (options.encodingType) { case EncodingTypePNG: - data = UIImagePNGRepresentation(image); + success(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 - if(options.sourceType != UIImagePickerControllerSourceTypeCamera){ + if(options.sourceType != UIImagePickerControllerSourceTypeCamera){ NSURL *url = info[UIImagePickerControllerReferenceURL]; + PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil]; PHAsset *asset = [result firstObject]; + + PHImageManager *manager = [PHImageManager defaultManager]; + PHImageRequestOptions *option = [PHImageRequestOptions alloc]; + option.synchronous = false; + + // Add a task to the group if (asset) { - PHImageManager *manager = [PHImageManager defaultManager]; - PHImageRequestOptions *option = [PHImageRequestOptions alloc]; - option.synchronous = true; [manager requestImageDataForAsset:asset options:option resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { - data = imageData; + data = imageData; + success(imageData); }]; } } else{ - return data = UIImageJPEGRepresentation(image, 1.0); + success(UIImageJPEGRepresentation(image, 1.0)); } + } else { - data = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f); + success(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) { + if (EXIFDictionary) { [self.metadata setObject:EXIFDictionary forKey:(NSString*)kCGImagePropertyExifDictionary]; } - + if (IsAtLeastiOSVersion(@"8.0")) { [[self locationManager] performSelector:NSSelectorFromString(@"requestWhenInUseAuthorization") withObject:nil afterDelay:0]; } @@ -401,10 +405,9 @@ - (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic } break; default: + success(nil); break; }; - - return data; } - (NSString*)tempFilePath:(NSString*)extension @@ -452,10 +455,10 @@ - (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)option - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info completion:(void (^)(CDVPluginResult* res))completion { - CDVPluginResult* result = nil; + __block CDVPluginResult* result = nil; BOOL saveToPhotoAlbum = options.saveToPhotoAlbum; UIImage* image = nil; - + switch (options.destinationType) { case DestinationTypeNativeUri: { @@ -481,46 +484,67 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp NSString* nativeUri = [[self urlTransformer:url] absoluteString]; result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nativeUri]; } + if (saveToPhotoAlbum && image) { + ALAssetsLibrary* library = [ALAssetsLibrary new]; + [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; + } + + completion(result); } 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]]; + //NSData* data = [self processImage:image info:info options:options]; + [self newProcessImage:image info:info options:options block:^(NSData* data) { + 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]]; + } } - } + if (saveToPhotoAlbum && image) { + ALAssetsLibrary* library = [ALAssetsLibrary new]; + [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; + } + + completion(result); + }]; } 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)]; - } + [self newProcessImage:image info:info options:options block:^(NSData* data) { + if (data) { + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)]; + } + if (saveToPhotoAlbum && image) { + ALAssetsLibrary* library = [ALAssetsLibrary new]; + [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; + } + + completion(result); + }]; } break; default: break; }; - - if (saveToPhotoAlbum && image) { - ALAssetsLibrary* library = [ALAssetsLibrary new]; - [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; - } - - completion(result); + + /*if (saveToPhotoAlbum && image) { + ALAssetsLibrary* library = [ALAssetsLibrary new]; + [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; + } + + completion(result);*/ } - (CDVPluginResult*)resultForVideo:(NSDictionary*)info From 2b854a710c6e0e50a77074da80d9c5142f78a211 Mon Sep 17 00:00:00 2001 From: JD Date: Mon, 29 Jan 2018 12:13:38 +0530 Subject: [PATCH 4/4] solved geolocation bug and removed extra comments --- src/ios/CDVCamera.m | 76 ++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/src/ios/CDVCamera.m b/src/ios/CDVCamera.m index ebf571d38..aa464fcd6 100644 --- a/src/ios/CDVCamera.m +++ b/src/ios/CDVCamera.m @@ -349,13 +349,18 @@ - (void)popoverControllerDidDismissPopover:(id)popoverController self.hasPendingOperation = NO; } typedef void(^successBlock)(NSData *); --(void) newProcessImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options block:(successBlock)success { +-(void) processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options block:(successBlock)success { __block NSData* data = nil; switch (options.encodingType) { - case EncodingTypePNG: - success(UIImagePNGRepresentation(image)); + case EncodingTypePNG: { + NSData *tempData = UIImagePNGRepresentation(image); + if (options.usesGeolocation) { + [self checkGeoLocation:info withData:tempData]; + } + success(tempData); 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))){ @@ -373,35 +378,32 @@ -(void) newProcessImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic if (asset) { [manager requestImageDataForAsset:asset options:option resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { data = imageData; + if (options.usesGeolocation) { + [self checkGeoLocation:info withData:data]; + } success(imageData); }]; } + else{ + success(nil); + } } else{ - success(UIImageJPEGRepresentation(image, 1.0)); + NSData *tempData = UIImageJPEGRepresentation(image, 1.0); + if (options.usesGeolocation) { + [self checkGeoLocation:info withData:tempData]; + } + success(tempData); } } else { - success(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]; + NSData *tempData = UIImageJPEGRepresentation(image, [options.quality floatValue] / 100.0f); + if (options.usesGeolocation) { + [self checkGeoLocation:info withData:tempData]; } + success(tempData); } + } break; default: @@ -410,6 +412,24 @@ -(void) newProcessImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPic }; } +-(void)checkGeoLocation:(NSDictionary*)info withData:(NSData*)data{ + 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]; + } +} + - (NSString*)tempFilePath:(NSString*)extension { NSString* docsPath = [NSTemporaryDirectory()stringByStandardizingPath]; @@ -495,8 +515,7 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp case DestinationTypeFileUri: { image = [self retrieveImage:info options:options]; - //NSData* data = [self processImage:image info:info options:options]; - [self newProcessImage:image info:info options:options block:^(NSData* data) { + [self processImage:image info:info options:options block:^(NSData* data) { if (data) { NSString* extension = options.encodingType == EncodingTypePNG? @"png" : @"jpg"; @@ -522,7 +541,7 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp case DestinationTypeDataUrl: { image = [self retrieveImage:info options:options]; - [self newProcessImage:image info:info options:options block:^(NSData* data) { + [self processImage:image info:info options:options block:^(NSData* data) { if (data) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)]; } @@ -538,13 +557,6 @@ - (void)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info comp default: break; }; - - /*if (saveToPhotoAlbum && image) { - ALAssetsLibrary* library = [ALAssetsLibrary new]; - [library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)(image.imageOrientation) completionBlock:nil]; - } - - completion(result);*/ } - (CDVPluginResult*)resultForVideo:(NSDictionary*)info