Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
<header-file src="src/ios/GMImagePicker/GMPHAsset.h" />
<source-file src="src/ios/GMImagePicker/GMPHAsset.m" />

<header-file src="src/ios/GMImagePicker/PHAsset+Meta.h" />
<source-file src="src/ios/GMImagePicker/PHAsset+Meta.m" />

<resource-file src="src/ios/GMImagePicker/[email protected]" />
<resource-file src="src/ios/GMImagePicker/[email protected]" />

Expand Down
3 changes: 2 additions & 1 deletion src/ios/GMImagePicker/GMFetchItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
@property (nonatomic, assign) double percent;
@property (nonatomic, strong) NSString * image_fullsize;
@property (nonatomic, strong) NSString * image_thumb;

@property (nonatomic, strong) NSString * video;
@property (nonatomic, strong) NSString * metadataJSON;

@property (nonatomic, assign) bool be_saving_img_thumb;
@property (nonatomic, assign) bool be_saving_img;
Expand Down
5 changes: 4 additions & 1 deletion src/ios/GMImagePicker/GMFetchItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@implementation GMFetchItem

@synthesize be_progressed, be_finished, percent, image_fullsize, image_thumb, be_saving_img, be_saving_img_thumb;
@synthesize be_progressed, be_finished, percent, image_fullsize, video, image_thumb, be_saving_img, be_saving_img_thumb, metadataJSON;

- (id)init{

Expand All @@ -22,10 +22,13 @@ - (id)init{

image_thumb = nil;
image_fullsize = nil;
video = nil;

be_saving_img = false;
be_saving_img_thumb;

metadataJSON = nil;

return self;
}

Expand Down
1 change: 1 addition & 0 deletions src/ios/GMImagePicker/GMGridViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import "GMImagePickerController.h"
#import "UIImage+fixOrientation.h"
#import "PHAsset+Meta.h"

#import <Photos/Photos.h>

Expand Down
64 changes: 60 additions & 4 deletions src/ios/GMImagePicker/GMGridViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#define CDV_PHOTO_PREFIX @"cdv_photo_"
#define CDV_THUMB_PREFIX @"cdv_thumb_"
#define CDV_VIDEO_PREFIX @"cdv_video_"


//Helper methods
Expand Down Expand Up @@ -394,7 +395,6 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
if ( fetch_item.be_saving_img_thumb==false && fetch_item.image_thumb == nil && result!= nil ) {

fetch_item.be_saving_img_thumb = true;

NSString * filePath;
do {
filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_THUMB_PREFIX, doc_thumbCount++, @"jpg"];
Expand Down Expand Up @@ -511,12 +511,42 @@ - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtInde
UIImage *imageToDisplay = result.fixOrientation; // UIImage+fixOrientation extension

NSLog(@"corrected orientation: %ld",(UIImageOrientation)imageToDisplay.imageOrientation);

// setting compression to a low value (high compression) impact performance, but not actual img quality
if ( ![ UIImageJPEGRepresentation(imageToDisplay, 0.2f ) writeToFile:filePath atomically:YES ] ) {
NSData * imageData = UIImageJPEGRepresentation(imageToDisplay, 1.0f );
// setting compression to a 1.0 => keep original quality
if ( ![ imageData writeToFile:filePath atomically:YES ] ) {
return;
}

[asset requestMetadataWithCompletionBlock:^(NSDictionary * _Nonnull metadata) {
//fetch_item.metadata = metadata;

NSError *error;
NSData *jsonData;
NSMutableDictionary * fetchMeta = [NSMutableDictionary new];
@try {
jsonData = [NSJSONSerialization dataWithJSONObject:[metadata objectForKey:@"{GPS}"] options:0 error:&error];
[fetchMeta setObject:[metadata objectForKey:@"{GPS}"] forKey:@"gps"];
} @catch (NSException *exception) {
NSLog(@"ERROR - %@", exception);
}

@try {
jsonData = [NSJSONSerialization dataWithJSONObject:[metadata objectForKey:@"{Exif}"] options:0 error:&error];
[fetchMeta setObject:[metadata objectForKey:@"{Exif}"] forKey:@"exif"];
} @catch (NSException *exception) {
NSLog(@"ERROR - %@", exception);
}
[fetchMeta setValue:filePath forKey:@"image_fullsize"];

NSDictionary *fetchMetaResult = [NSDictionary dictionaryWithDictionary:fetchMeta];


jsonData = [NSJSONSerialization dataWithJSONObject:fetchMetaResult options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
fetch_item.metadataJSON = jsonString;

}];

fetch_item.image_fullsize = filePath;
fetch_item.be_saving_img = false;

Expand Down Expand Up @@ -556,6 +586,10 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa
//GMFetchItem * fetch_item = [dic_asset_fetches objectForKey:[ NSNumber numberWithLong:indexPath.item ]];
GMFetchItem * fetch_item = [dic_asset_fetches objectForKey:asset];

if (asset.mediaType==PHAssetMediaTypeVideo){
[self exportVideoAsset:asset andIndex:indexPath.item andFetchAsset:fetch_item];
}

[self.picker selectAsset:asset];
[self.picker selectFetchItem:fetch_item];

Expand Down Expand Up @@ -766,5 +800,27 @@ - (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths
return assets;
}

#pragma mark - VideoAssets
-(void)exportVideoAsset:(PHAsset *)asset andIndex:(int)index andFetchAsset:(GMFetchItem *)fetchItem{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Preparing video"
message:@"Please wait..."
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];

[self.imageManager requestExportSessionForVideo:asset options:nil exportPreset:@"AVAssetExportPresetPassthrough" resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
NSString *filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_VIDEO_PREFIX, index, @"mov"];
exportSession.outputURL = [NSURL fileURLWithPath:filePath];
exportSession.outputFileType = AVFileTypeMPEG4;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
fetchItem.video = filePath;
[alert dismissViewControllerAnimated:YES completion:^{}];
});
}];
});
}];
}


@end
51 changes: 51 additions & 0 deletions src/ios/GMImagePicker/PHAsset+Meta.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// PHAsset+Meta.h
// CordovaPlugins
//
// Created by Alexander on 11/19/15.
// Copyright © 2015 Kentdome, LLC. All rights reserved.
//

#import <Foundation/Foundation.h>
@import Photos;

#import <objc/runtime.h>

#import <Photos/PHAsset.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^PHAssetStringBlock)(NSString *string);
typedef void (^PHAssetBoolBlock)(BOOL success);
typedef void (^PHAssetMetadataBlock)(NSDictionary *metadata);

@interface PHAsset (Meta)

-(void)setMetadata:(NSDictionary *)metadata;

/*!
@method requestUniformTypeWithCompletionBlock
@description Get system-declared uniform type identifiers of an asset (com.compuserve.gif, public.png, etc)
@param completionBlock This block is passed a string. This parameter may be nil.
*/
-(void)requestUniformTypeWithCompletionBlock:(PHAssetStringBlock)completionBlock;

/*!
@method requestMetadataWithOptions:options:completionBlock
@description Get metadata dictionary of an asset (contains sub-dictionaries EXIF, GPS etc)
@param options An PHContentEditingInputRequestOptions to specify options of a PHAsset object (networkAccessAllowed, progressHandler)
@param completionBlock This block is passed a dictionary of metadata properties. This parameter may be nil.
*/
-(void)requestMetadataWithOptions:(PHContentEditingInputRequestOptions*)options completionBlock:(PHAssetMetadataBlock)completionBlock;


/*!
@method requestMetadataWithCompletionBlock
@description Get metadata dictionary of an asset (contains sub-dictionaries EXIF, GPS etc)
@param completionBlock This block is passed a dictionary of metadata properties. This parameter may be nil.
*/
-(void)requestMetadataWithCompletionBlock:(PHAssetMetadataBlock)completionBlock;

@end

NS_ASSUME_NONNULL_END
57 changes: 57 additions & 0 deletions src/ios/GMImagePicker/PHAsset+Meta.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// PHAsset+Meta.m
// PHAssetTest
//
// Created by Alexander on 11/19/15.
// Copyright © 2015 Kentdome, LLC. All rights reserved.
//

#import "PHAsset+Meta.h"

@implementation PHAsset (Meta)

-(void)requestUniformTypeWithCompletionBlock:(PHAssetStringBlock)completionBlock{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.networkAccessAllowed = YES;
PHImageManager *manager = [[PHImageManager alloc] init];
[manager requestImageDataForAsset:self options:options resultHandler:
^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(dataUTI);
});
}];
});
}


-(void)requestMetadataWithOptions:(PHContentEditingInputRequestOptions*)options completionBlock:(PHAssetMetadataBlock)completionBlock{
if(self.mediaType == PHAssetMediaTypeImage){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
CIImage *image = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(image.properties);
});
}];

});
}
}


-(void)requestMetadataWithCompletionBlock:(PHAssetMetadataBlock)completionBlock{
PHImageRequestOptions *options = [PHImageRequestOptions new];
options.networkAccessAllowed = YES;
options.synchronous = YES;
options.version = PHImageRequestOptionsVersionOriginal;
PHImageManager *manager = [[PHImageManager alloc] init];
[manager requestImageDataForAsset:self options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info){
CIImage *image = [CIImage imageWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(image.properties);
});
}];
}

@end
11 changes: 9 additions & 2 deletions src/ios/SOSPicker.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

typedef enum : NSUInteger {
FILE_URI = 0,
BASE64_STRING = 1
BASE64_STRING = 1,
METADATA_JSON = 2
} SOSPickerOutputType;

@interface SOSPicker () <GMImagePickerControllerDelegate>
Expand Down Expand Up @@ -195,6 +196,11 @@ - (void)assetsPickerController:(GMImagePickerController *)picker didFinishPickin
continue;
}

if (item.video!=nil){
[result_all addObject:item.video];
continue;
}

do {
filePath = [NSString stringWithFormat:@"%@/%@%03d.%@", docsPath, CDV_PHOTO_PREFIX, i++, @"jpg"];
} while ([fileMgr fileExistsAtPath:filePath]);
Expand All @@ -208,7 +214,8 @@ - (void)assetsPickerController:(GMImagePickerController *)picker didFinishPickin
} else {
if (self.quality == 100) {
// no scaling, no downsampling, this is the fastest option
[result_all addObject:item.image_fullsize];
//[result_all addObject:item.image_fullsize];
[result_all addObject:item.metadataJSON];
} else {
// resample first
UIImage* image = [UIImage imageNamed:item.image_fullsize];
Expand Down