123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- #import <Foundation/Foundation.h>
- #import <MobileCoreServices/UTCoreTypes.h>
- #import <ImageIO/ImageIO.h>
- #import <AVFoundation/AVFoundation.h>
- #import <UIKit/UIKit.h>
-
- #ifdef UNITY_4_0 || UNITY_5_0
- #import "iPhone_View.h"
- #else
- extern UIViewController* UnityGetGLViewController();
- #endif
-
- #define CHECK_IOS_VERSION( version ) ([[[UIDevice currentDevice] systemVersion] compare:version options:NSNumericSearch] != NSOrderedAscending)
-
- @interface UNativeCamera:NSObject
- + (int)checkPermission;
- + (int)requestPermission:(BOOL)asyncMode;
- + (int)canOpenSettings;
- + (void)openSettings;
- + (int)hasCamera;
- + (void)openCamera:(BOOL)imageMode defaultCamera:(int)defaultCamera savePath:(NSString *)imageSavePath maxImageSize:(int)maxImageSize videoQuality:(int)videoQuality maxVideoDuration:(int)maxVideoDuration;
- + (int)isCameraBusy;
- + (char *)getImageProperties:(NSString *)path;
- + (char *)getVideoProperties:(NSString *)path;
- + (char *)getVideoThumbnail:(NSString *)path savePath:(NSString *)savePath maximumSize:(int)maximumSize captureTime:(double)captureTime;
- + (char *)loadImageAtPath:(NSString *)path tempFilePath:(NSString *)tempFilePath maximumSize:(int)maximumSize;
- @end
-
- @implementation UNativeCamera
-
- static NSString *pickedMediaSavePath;
- static UIImagePickerController *imagePicker;
- static int cameraMaxImageSize = -1;
- static int imagePickerState = 0; // 0 -> none, 1 -> showing, 2 -> finished
- static BOOL recordingVideo = NO;
- static AVAudioSessionCategory unityAudioSessionCategory = AVAudioSessionCategoryAmbient;
- static NSUInteger unityAudioSessionCategoryOptions = 1;
- static AVAudioSessionMode unityAudioSessionMode = AVAudioSessionModeDefault;
-
- // Credit: https://stackoverflow.com/a/20464727/2373034
- + (int)checkPermission
- {
- if( CHECK_IOS_VERSION( @"7.0" ) )
- {
- AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
- if( status == AVAuthorizationStatusAuthorized )
- return 1;
- else if( status == AVAuthorizationStatusNotDetermined )
- return 2;
- else
- return 0;
- }
-
- return 1;
- }
-
- // Credit: https://stackoverflow.com/a/20464727/2373034
- + (int)requestPermission:(BOOL)asyncMode
- {
- int result = [self requestPermissionInternal:asyncMode];
- if( asyncMode && result >= 0 ) // Result returned immediately, forward it
- UnitySendMessage( "NCPermissionCallbackiOS", "OnPermissionRequested", [self getCString:[NSString stringWithFormat:@"%d", result]] );
-
- return result;
- }
-
- + (int)requestPermissionInternal:(BOOL)asyncMode
- {
- if( CHECK_IOS_VERSION( @"7.0" ) )
- {
- AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
- if( status == AVAuthorizationStatusAuthorized )
- return 1;
- else if( status == AVAuthorizationStatusNotDetermined )
- {
- if( asyncMode )
- {
- [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^( BOOL granted )
- {
- UnitySendMessage( "NCPermissionCallbackiOS", "OnPermissionRequested", granted ? "1" : "0" );
- }];
-
- return -1;
- }
- else
- {
- __block BOOL authorized = NO;
- dispatch_semaphore_t sema = dispatch_semaphore_create( 0 );
- [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^( BOOL granted )
- {
- authorized = granted;
- dispatch_semaphore_signal( sema );
- }];
- dispatch_semaphore_wait( sema, DISPATCH_TIME_FOREVER );
-
- return authorized ? 1 : 0;
- }
- }
- else
- return 0;
- }
-
- return 1;
- }
-
- // Credit: https://stackoverflow.com/a/25453667/2373034
- + (int)canOpenSettings
- {
- return ( &UIApplicationOpenSettingsURLString != NULL ) ? 1 : 0;
- }
-
- // Credit: https://stackoverflow.com/a/25453667/2373034
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- + (void)openSettings
- {
- if( &UIApplicationOpenSettingsURLString != NULL )
- {
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
- if( CHECK_IOS_VERSION( @"10.0" ) )
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
- else
- #endif
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }
- }
- #pragma clang diagnostic pop
-
- + (int)hasCamera
- {
- return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? 1 : 0;
- }
-
- // Credit: https://stackoverflow.com/a/10531752/2373034
- + (void)openCamera:(BOOL)imageMode defaultCamera:(int)defaultCamera savePath:(NSString *)imageSavePath maxImageSize:(int)maxImageSize videoQuality:(int)videoQuality maxVideoDuration:(int)maxVideoDuration
- {
- if( ![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] )
- {
- NSLog( @"Device has no registered cameras!" );
-
- UnitySendMessage( "NCCameraCallbackiOS", "OnMediaReceived", "" );
- return;
- }
-
- if( ( imageMode && ![[UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera] containsObject:(NSString*)kUTTypeImage] ) ||
- ( !imageMode && ![[UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera] containsObject:(NSString*)kUTTypeMovie] ) )
- {
- NSLog( @"Camera does not support this operation!" );
-
- UnitySendMessage( "NCCameraCallbackiOS", "OnMediaReceived", "" );
- return;
- }
-
- imagePicker = [[UIImagePickerController alloc] init];
- imagePicker.delegate = (id) self;
- imagePicker.allowsEditing = NO;
- imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
-
- if( imageMode )
- imagePicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
- else
- {
- imagePicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
-
- if( maxVideoDuration > 0 )
- imagePicker.videoMaximumDuration = maxVideoDuration;
-
- if( videoQuality == 0 )
- imagePicker.videoQuality = UIImagePickerControllerQualityTypeLow;
- else if( videoQuality == 1 )
- imagePicker.videoQuality = UIImagePickerControllerQualityTypeMedium;
- else if( videoQuality == 2 )
- imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
- }
-
- if( defaultCamera == 0 && [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear] )
- imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
- else if( defaultCamera == 1 && [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront] )
- imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
-
- // Bugfix for https://github.com/yasirkula/UnityNativeCamera/issues/45
- if( !imageMode )
- {
- unityAudioSessionCategory = [[AVAudioSession sharedInstance] category];
- unityAudioSessionCategoryOptions = [[AVAudioSession sharedInstance] categoryOptions];
- unityAudioSessionMode = [[AVAudioSession sharedInstance] mode];
- }
-
- recordingVideo = !imageMode;
- pickedMediaSavePath = imageSavePath;
- cameraMaxImageSize = maxImageSize;
-
- imagePickerState = 1;
- [UnityGetGLViewController() presentViewController:imagePicker animated:YES completion:^{ imagePickerState = 0; }];
- }
-
- + (int)isCameraBusy
- {
- if( imagePickerState == 2 )
- return 1;
-
- if( imagePicker != nil )
- {
- if( imagePickerState == 1 || [imagePicker presentingViewController] == UnityGetGLViewController() )
- return 1;
-
- imagePicker = nil;
- [self restoreAudioSession];
-
- return 0;
- }
-
- return 0;
- }
-
- + (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
- {
- NSString *path = nil;
- if( [info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeImage] )
- {
- NSLog( @"UIImagePickerController finished taking picture" );
-
- UIImage *image = info[UIImagePickerControllerEditedImage] ?: info[UIImagePickerControllerOriginalImage];
- if( image == nil )
- path = nil;
- else
- {
- NSString *extension = [pickedMediaSavePath pathExtension];
- BOOL saveAsJPEG = [extension caseInsensitiveCompare:@"jpg"] == NSOrderedSame || [extension caseInsensitiveCompare:@"jpeg"] == NSOrderedSame;
-
- // Try to save the image with metadata
- // CANCELED: a number of users reported that this method results in 90-degree rotated images, uncomment at your own risk
- // Credit: https://stackoverflow.com/a/15858955
- /*NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
- NSMutableDictionary *mutableMetadata = nil;
- CFDictionaryRef metadataRef;
- CFStringRef imageType;
-
- if( saveAsJPEG )
- {
- mutableMetadata = [metadata mutableCopy];
- [mutableMetadata setObject:@(1.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality];
-
- metadataRef = (__bridge CFDictionaryRef) mutableMetadata;
- imageType = kUTTypeJPEG;
- }
- else
- {
- metadataRef = (__bridge CFDictionaryRef) metadata;
- imageType = kUTTypePNG;
- }
-
- CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL( (__bridge CFURLRef) [NSURL fileURLWithPath:pickedMediaSavePath], imageType , 1, NULL );
- if( imageDestination == NULL )
- NSLog( @"Failed to create image destination" );
- else
- {
- CGImageDestinationAddImage( imageDestination, image.CGImage, metadataRef );
- if( CGImageDestinationFinalize( imageDestination ) )
- path = pickedMediaSavePath;
- else
- NSLog( @"Failed to finalize the image" );
-
- CFRelease( imageDestination );
- }*/
-
- if( path == nil )
- {
- //NSLog( @"Attempting to save the image without metadata as fallback" );
-
- if( ( saveAsJPEG && [UIImageJPEGRepresentation( [self scaleImage:image maxSize:cameraMaxImageSize], 1.0 ) writeToFile:pickedMediaSavePath atomically:YES] ) ||
- ( !saveAsJPEG && [UIImagePNGRepresentation( [self scaleImage:image maxSize:cameraMaxImageSize] ) writeToFile:pickedMediaSavePath atomically:YES] ) )
- path = pickedMediaSavePath;
- else
- {
- NSLog( @"Error saving image without metadata" );
- path = nil;
- }
- }
- }
- }
- else
- {
- NSLog( @"UIImagePickerController finished recording video" );
-
- NSURL *mediaUrl = info[UIImagePickerControllerMediaURL] ?: info[UIImagePickerControllerReferenceURL];
- if( mediaUrl == nil )
- path = nil;
- else
- path = [mediaUrl path];
- }
-
- imagePicker = nil;
- imagePickerState = 2;
- UnitySendMessage( "NCCameraCallbackiOS", "OnMediaReceived", [self getCString:path] );
-
- [picker dismissViewControllerAnimated:NO completion:nil];
- [self restoreAudioSession];
- }
-
- + (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
- {
- NSLog( @"UIImagePickerController cancelled" );
-
- imagePicker = nil;
- UnitySendMessage( "NCCameraCallbackiOS", "OnMediaReceived", "" );
-
- [picker dismissViewControllerAnimated:NO completion:nil];
- [self restoreAudioSession];
- }
-
- // Bugfix for https://github.com/yasirkula/UnityNativeCamera/issues/45
- + (void)restoreAudioSession
- {
- if( recordingVideo )
- {
- BOOL audioModeSwitchResult = YES;
- NSError *error = nil;
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
- if( CHECK_IOS_VERSION( @"10.0" ) )
- audioModeSwitchResult = [[AVAudioSession sharedInstance] setCategory:unityAudioSessionCategory mode:unityAudioSessionMode options:unityAudioSessionCategoryOptions error:&error];
- else
- #endif
- audioModeSwitchResult = [[AVAudioSession sharedInstance] setCategory:unityAudioSessionCategory withOptions:unityAudioSessionCategoryOptions error:&error] && [[AVAudioSession sharedInstance] setMode:unityAudioSessionMode error:&error];
-
- if( !audioModeSwitchResult )
- {
- if( error != nil )
- NSLog( @"Error setting audio session category back to %@ with mode %@ and options %lu: %@", unityAudioSessionCategory, unityAudioSessionMode, (unsigned long) unityAudioSessionCategoryOptions, error );
- else
- NSLog( @"Error setting audio session category back to %@ with mode %@ and options %lu", unityAudioSessionCategory, unityAudioSessionMode, (unsigned long) unityAudioSessionCategoryOptions );
- }
- }
- }
-
- // Credit: https://stackoverflow.com/a/4170099/2373034
- + (NSArray *)getImageMetadata:(NSString *)path
- {
- int width = 0;
- int height = 0;
- int orientation = -1;
-
- CGImageSourceRef imageSource = CGImageSourceCreateWithURL( (__bridge CFURLRef) [NSURL fileURLWithPath:path], nil );
- if( imageSource != nil )
- {
- NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:(__bridge NSString *)kCGImageSourceShouldCache];
- CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex( imageSource, 0, (__bridge CFDictionaryRef) options );
- CFRelease( imageSource );
-
- CGFloat widthF = 0.0f, heightF = 0.0f;
- if( imageProperties != nil )
- {
- if( CFDictionaryContainsKey( imageProperties, kCGImagePropertyPixelWidth ) )
- CFNumberGetValue( (CFNumberRef) CFDictionaryGetValue( imageProperties, kCGImagePropertyPixelWidth ), kCFNumberCGFloatType, &widthF );
-
- if( CFDictionaryContainsKey( imageProperties, kCGImagePropertyPixelHeight ) )
- CFNumberGetValue( (CFNumberRef) CFDictionaryGetValue( imageProperties, kCGImagePropertyPixelHeight ), kCFNumberCGFloatType, &heightF );
-
- if( CFDictionaryContainsKey( imageProperties, kCGImagePropertyOrientation ) )
- {
- CFNumberGetValue( (CFNumberRef) CFDictionaryGetValue( imageProperties, kCGImagePropertyOrientation ), kCFNumberIntType, &orientation );
-
- if( orientation > 4 )
- {
- // Landscape image
- CGFloat temp = widthF;
- widthF = heightF;
- heightF = temp;
- }
- }
-
- CFRelease( imageProperties );
- }
-
- width = (int) roundf( widthF );
- height = (int) roundf( heightF );
- }
-
- return [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:width], [NSNumber numberWithInt:height], [NSNumber numberWithInt:orientation], nil];
- }
-
- + (char *)getImageProperties:(NSString *)path
- {
- NSArray *metadata = [self getImageMetadata:path];
-
- int orientationUnity;
- int orientation = [metadata[2] intValue];
-
- // To understand the magic numbers, see ImageOrientation enum in NativeCamera.cs
- // and http://sylvana.net/jpegcrop/exif_orientation.html
- if( orientation == 1 )
- orientationUnity = 0;
- else if( orientation == 2 )
- orientationUnity = 4;
- else if( orientation == 3 )
- orientationUnity = 2;
- else if( orientation == 4 )
- orientationUnity = 6;
- else if( orientation == 5 )
- orientationUnity = 5;
- else if( orientation == 6 )
- orientationUnity = 1;
- else if( orientation == 7 )
- orientationUnity = 7;
- else if( orientation == 8 )
- orientationUnity = 3;
- else
- orientationUnity = -1;
-
- return [self getCString:[NSString stringWithFormat:@"%d>%d> >%d", [metadata[0] intValue], [metadata[1] intValue], orientationUnity]];
- }
-
- + (char *)getVideoProperties:(NSString *)path
- {
- CGSize size = CGSizeZero;
- float rotation = 0;
- long long duration = 0;
-
- AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
- if( asset != nil )
- {
- duration = (long long) round( CMTimeGetSeconds( [asset duration] ) * 1000 );
- CGAffineTransform transform = [asset preferredTransform];
- NSArray<AVAssetTrack *>* videoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
- if( videoTracks != nil && [videoTracks count] > 0 )
- {
- size = [[videoTracks objectAtIndex:0] naturalSize];
- transform = [[videoTracks objectAtIndex:0] preferredTransform];
- }
-
- rotation = atan2( transform.b, transform.a ) * ( 180.0 / M_PI );
- }
-
- return [self getCString:[NSString stringWithFormat:@"%d>%d>%lld>%f", (int) roundf( size.width ), (int) roundf( size.height ), duration, rotation]];
- }
-
- + (char *)getVideoThumbnail:(NSString *)path savePath:(NSString *)savePath maximumSize:(int)maximumSize captureTime:(double)captureTime
- {
- AVAssetImageGenerator *thumbnailGenerator = [[AVAssetImageGenerator alloc] initWithAsset:[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:path] options:nil]];
- thumbnailGenerator.appliesPreferredTrackTransform = YES;
- thumbnailGenerator.maximumSize = CGSizeMake( (CGFloat) maximumSize, (CGFloat) maximumSize );
- thumbnailGenerator.requestedTimeToleranceBefore = kCMTimeZero;
- thumbnailGenerator.requestedTimeToleranceAfter = kCMTimeZero;
-
- if( captureTime < 0.0 )
- captureTime = 0.0;
- else
- {
- AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
- if( asset != nil )
- {
- double videoDuration = CMTimeGetSeconds( [asset duration] );
- if( videoDuration > 0.0 && captureTime >= videoDuration - 0.1 )
- {
- if( captureTime > videoDuration )
- captureTime = videoDuration;
-
- thumbnailGenerator.requestedTimeToleranceBefore = CMTimeMakeWithSeconds( 1.0, 600 );
- }
- }
- }
-
- NSError *error = nil;
- CGImageRef image = [thumbnailGenerator copyCGImageAtTime:CMTimeMakeWithSeconds( captureTime, 600 ) actualTime:nil error:&error];
- if( image == nil )
- {
- if( error != nil )
- NSLog( @"Error generating video thumbnail: %@", error );
- else
- NSLog( @"Error generating video thumbnail..." );
-
- return [self getCString:@""];
- }
-
- UIImage *thumbnail = [[UIImage alloc] initWithCGImage:image];
- CGImageRelease( image );
-
- if( ![UIImagePNGRepresentation( thumbnail ) writeToFile:savePath atomically:YES] )
- {
- NSLog( @"Error saving thumbnail image" );
- return [self getCString:@""];
- }
-
- return [self getCString:savePath];
- }
-
- + (UIImage *)scaleImage:(UIImage *)image maxSize:(int)maxSize
- {
- CGFloat width = image.size.width;
- CGFloat height = image.size.height;
-
- UIImageOrientation orientation = image.imageOrientation;
- if( width <= maxSize && height <= maxSize && orientation != UIImageOrientationDown &&
- orientation != UIImageOrientationLeft && orientation != UIImageOrientationRight &&
- orientation != UIImageOrientationLeftMirrored && orientation != UIImageOrientationRightMirrored &&
- orientation != UIImageOrientationUpMirrored && orientation != UIImageOrientationDownMirrored )
- return image;
-
- CGFloat scaleX = 1.0f;
- CGFloat scaleY = 1.0f;
- if( width > maxSize )
- scaleX = maxSize / width;
- if( height > maxSize )
- scaleY = maxSize / height;
-
- // Credit: https://github.com/mbcharbonneau/UIImage-Categories/blob/master/UIImage%2BAlpha.m
- CGImageAlphaInfo alpha = CGImageGetAlphaInfo( image.CGImage );
- BOOL hasAlpha = alpha == kCGImageAlphaFirst || alpha == kCGImageAlphaLast || alpha == kCGImageAlphaPremultipliedFirst || alpha == kCGImageAlphaPremultipliedLast;
-
- CGFloat scaleRatio = scaleX < scaleY ? scaleX : scaleY;
- CGRect imageRect = CGRectMake( 0, 0, width * scaleRatio, height * scaleRatio );
- UIGraphicsBeginImageContextWithOptions( imageRect.size, !hasAlpha, image.scale );
- [image drawInRect:imageRect];
- image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- return image;
- }
-
- + (char *)loadImageAtPath:(NSString *)path tempFilePath:(NSString *)tempFilePath maximumSize:(int)maximumSize
- {
- // Check if the image can be loaded by Unity without requiring a conversion to PNG
- // Credit: https://stackoverflow.com/a/12048937/2373034
- NSString *extension = [path pathExtension];
- BOOL conversionNeeded = [extension caseInsensitiveCompare:@"jpg"] != NSOrderedSame && [extension caseInsensitiveCompare:@"jpeg"] != NSOrderedSame && [extension caseInsensitiveCompare:@"png"] != NSOrderedSame;
-
- if( !conversionNeeded )
- {
- // Check if the image needs to be processed at all
- NSArray *metadata = [self getImageMetadata:path];
- int orientationInt = [metadata[2] intValue]; // 1: correct orientation, [1,8]: valid orientation range
- if( orientationInt == 1 && [metadata[0] intValue] <= maximumSize && [metadata[1] intValue] <= maximumSize )
- return [self getCString:path];
- }
-
- UIImage *image = [UIImage imageWithContentsOfFile:path];
- if( image == nil )
- return [self getCString:path];
-
- UIImage *scaledImage = [self scaleImage:image maxSize:maximumSize];
- if( conversionNeeded || scaledImage != image )
- {
- if( ![UIImagePNGRepresentation( scaledImage ) writeToFile:tempFilePath atomically:YES] )
- {
- NSLog( @"Error creating scaled image" );
- return [self getCString:path];
- }
-
- return [self getCString:tempFilePath];
- }
- else
- return [self getCString:path];
- }
-
- // Credit: https://stackoverflow.com/a/37052118/2373034
- + (char *)getCString:(NSString *)source
- {
- if( source == nil )
- source = @"";
-
- const char *sourceUTF8 = [source UTF8String];
- char *result = (char*) malloc( strlen( sourceUTF8 ) + 1 );
- strcpy( result, sourceUTF8 );
-
- return result;
- }
-
- @end
-
- extern "C" int _NativeCamera_CheckPermission()
- {
- return [UNativeCamera checkPermission];
- }
-
- extern "C" int _NativeCamera_RequestPermission( int asyncMode )
- {
- return [UNativeCamera requestPermission:( asyncMode == 1 )];
- }
-
- extern "C" int _NativeCamera_CanOpenSettings()
- {
- return [UNativeCamera canOpenSettings];
- }
-
- extern "C" void _NativeCamera_OpenSettings()
- {
- [UNativeCamera openSettings];
- }
-
- extern "C" int _NativeCamera_HasCamera()
- {
- return [UNativeCamera hasCamera];
- }
-
- extern "C" void _NativeCamera_TakePicture( const char* imageSavePath, int maxSize, int preferredCamera )
- {
- [UNativeCamera openCamera:YES defaultCamera:preferredCamera savePath:[NSString stringWithUTF8String:imageSavePath] maxImageSize:maxSize videoQuality:-1 maxVideoDuration:-1];
- }
-
- extern "C" void _NativeCamera_RecordVideo( int quality, int maxDuration, int preferredCamera )
- {
- [UNativeCamera openCamera:NO defaultCamera:preferredCamera savePath:nil maxImageSize:4096 videoQuality:quality maxVideoDuration:maxDuration];
- }
-
- extern "C" int _NativeCamera_IsCameraBusy()
- {
- return [UNativeCamera isCameraBusy];
- }
-
- extern "C" char* _NativeCamera_GetImageProperties( const char* path )
- {
- return [UNativeCamera getImageProperties:[NSString stringWithUTF8String:path]];
- }
-
- extern "C" char* _NativeCamera_GetVideoProperties( const char* path )
- {
- return [UNativeCamera getVideoProperties:[NSString stringWithUTF8String:path]];
- }
-
- extern "C" char* _NativeCamera_GetVideoThumbnail( const char* path, const char* thumbnailSavePath, int maxSize, double captureTimeInSeconds )
- {
- return [UNativeCamera getVideoThumbnail:[NSString stringWithUTF8String:path] savePath:[NSString stringWithUTF8String:thumbnailSavePath] maximumSize:maxSize captureTime:captureTimeInSeconds];
- }
-
- extern "C" char* _NativeCamera_LoadImageAtPath( const char* path, const char* temporaryFilePath, int maxSize )
- {
- return [UNativeCamera loadImageAtPath:[NSString stringWithUTF8String:path] tempFilePath:[NSString stringWithUTF8String:temporaryFilePath] maximumSize:maxSize];
- }
|