Skip to content

Commit 5745331

Browse files
committed
allow to specify target
1 parent f89bba4 commit 5745331

File tree

4 files changed

+101
-23
lines changed

4 files changed

+101
-23
lines changed

ARKit.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ Object.keys(ARKitManager).forEach(key => {
156156
ARKit[key] = ARKitManager[key];
157157
});
158158

159+
const addDefaultsToSnapShotFunc = funcName => ({ target = 'cameraRoll' }) =>
160+
ARKitManager[funcName]({ target });
161+
162+
ARKit.snapshot = addDefaultsToSnapShotFunc('snapshot');
163+
ARKit.snapshotCamera = addDefaultsToSnapShotFunc('snapshotCamera');
164+
159165
ARKit.exportModel = presetId => {
160166
const id = presetId || generateId();
161167
const property = { id };

ios/RCTARKit.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error
5656
- (void)hitTestSceneObjects:(CGPoint)tapPoint resolve:(RCTARKitResolve) resolve reject:(RCTARKitReject)reject;
5757
- (SCNVector3)projectPoint:(SCNVector3)point;
5858
- (float)getCameraDistanceToPoint:(SCNVector3)point;
59-
- (void)snapshot:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject;
60-
- (void)snapshotCamera:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject;
59+
- (UIImage *)getSnaphshot;
60+
- (UIImage *)getSnaphshotCamera;
6161
- (void)focusScene;
6262
- (void)clearScene;
6363
- (NSDictionary *)readCameraPosition;

ios/RCTARKit.m

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -231,40 +231,32 @@ - (void)hitTestSceneObjects:(const CGPoint)tapPoint resolve:(RCTARKitResolve)res
231231
}
232232

233233

234-
- (void)snapshot:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject {
234+
- (UIImage *)getSnaphshot {
235235
UIImage *image = [self.arView snapshot];
236-
// FIXME: I belive this is not the right way. I don't know how to pass 'resolve' to the completionSelector
237-
// If you know how to do it, please PR. Thanks!
238-
_resolve = resolve;
239-
UIImageWriteToSavedPhotosAlbum(image, self, @selector(thisImage:savedInAlbumWithError:ctx:), NULL);
236+
return image;
240237
}
241238

242239

243-
- (void)snapshotCamera:(RCTARKitResolve)resolve reject:(RCTARKitReject)reject {
244240

245-
// thx https://stackoverflow.com/a/8094038/1463534
241+
242+
243+
- (UIImage *)getSnaphsotCamera {
246244
CVPixelBufferRef pixelBuffer = self.arView.session.currentFrame.capturedImage;
247245
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
248-
246+
249247
CIContext *temporaryContext = [CIContext contextWithOptions:nil];
250248
CGImageRef videoImage = [temporaryContext
251249
createCGImage:ciImage
252250
fromRect:CGRectMake(0, 0,
253251
CVPixelBufferGetWidth(pixelBuffer),
254252
CVPixelBufferGetHeight(pixelBuffer))];
255-
253+
256254
UIImage *image = [UIImage imageWithCGImage:videoImage scale: 1.0 orientation:UIImageOrientationRight];
257255
CGImageRelease(videoImage);
258-
_resolve = resolve;
259-
UIImageWriteToSavedPhotosAlbum(image, self, @selector(thisImage:savedInAlbumWithError:ctx:), NULL);
256+
return image;
260257
}
261258

262-
- (void)thisImage:(UIImage *)image savedInAlbumWithError:(NSError *)error ctx:(void *)ctx {
263-
if (error) {
264-
} else {
265-
_resolve(@{ @"success": @(YES) });
266-
}
267-
}
259+
268260

269261

270262

ios/RCTARKitManager.m

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#import "RCTARKitManager.h"
1010
#import "RCTARKit.h"
1111
#import "RCTARKitNodes.h"
12+
#import <UIKit/UIKit.h>
13+
#import <Photos/Photos.h>
1214

1315
@implementation RCTARKitManager
1416

@@ -95,12 +97,90 @@ - (NSDictionary *)constantsToExport
9597

9698

9799

98-
RCT_EXPORT_METHOD(snapshot:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
99-
[[ARKit sharedInstance] snapshot:resolve reject:reject];
100+
- (NSString *)getAssetUrl:(NSString *)localID {
101+
// thx https://stackoverflow.com/a/34788748/1463534
102+
// heck, objective c is such a mess
103+
NSString * assetID = [localID stringByReplacingOccurrencesOfString:@"/.*" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [localID length])];
104+
NSString * ext = @"JPG";
105+
NSString * assetURLStr = [NSString stringWithFormat:@"assets-library://asset/asset.%@?id=%@&ext=%@", ext, assetID, ext];
106+
return assetURLStr;
100107
}
101108

102-
RCT_EXPORT_METHOD(snapshotCamera:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
103-
[[ARKit sharedInstance] snapshotCamera:resolve reject:reject];
109+
- (void)storeImageInPhotoAlbum:(UIImage *)image reject:(RCTPromiseRejectBlock)reject resolve:(RCTPromiseResolveBlock)resolve {
110+
__block PHObjectPlaceholder *placeholder;
111+
112+
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
113+
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
114+
placeholder = [createAssetRequest placeholderForCreatedAsset];
115+
116+
} completionHandler:^(BOOL success, NSError *error) {
117+
if (success)
118+
{
119+
120+
NSString * localID = placeholder.localIdentifier;
121+
122+
NSString * assetURLStr = [self getAssetUrl:localID];
123+
124+
resolve(@{@"url": assetURLStr});
125+
}
126+
else
127+
{
128+
reject(@"snapshot_error", @"Could not store snapshot", error);
129+
}
130+
}];
131+
}
132+
133+
134+
- (void)storeImageInDirectory:(UIImage *)image directory:(NSString *)directory reject:(RCTPromiseRejectBlock)reject resolve:(RCTPromiseResolveBlock)resolve {
135+
136+
NSData *pngData = UIImagePNGRepresentation(image);
137+
138+
NSString *prefixString = @"capture";
139+
140+
NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString] ;
141+
NSString *uniqueFileName = [NSString stringWithFormat:@"%@_%@.png", prefixString, guid];
142+
143+
NSString *filePath = [directory stringByAppendingPathComponent:uniqueFileName]; //Add the file name
144+
bool success = [pngData writeToFile:filePath atomically:YES]; //Write the file
145+
if(success) {
146+
resolve(@{@"url": filePath});
147+
} else {
148+
// TODO use NSError from writeToFile
149+
reject(@"snapshot_error", [NSString stringWithFormat:@"could not save to '%@'", filePath], nil);
150+
}
151+
152+
}
153+
154+
- (void)storeImage:(UIImage *)image options:(NSDictionary *)options reject:(RCTPromiseRejectBlock)reject resolve:(RCTPromiseResolveBlock)resolve {
155+
NSString * target = @"cameraRoll";
156+
if(options[@"target"]) {
157+
target = options[@"target"];
158+
}
159+
if([target isEqualToString:@"cameraRoll"]) {
160+
// camera roll / photo album
161+
[self storeImageInPhotoAlbum:image reject:reject resolve:resolve];
162+
} else if([target isEqualToString:@"cache"]) {
163+
NSString * cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
164+
[self storeImageInDirectory:image directory:cacheDir reject:reject resolve:resolve];
165+
} else if([target isEqualToString:@"documents"]) {
166+
NSString * documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
167+
[self storeImageInDirectory:image directory:documentsDir reject:reject resolve:resolve];
168+
} else {
169+
[self storeImageInDirectory:image directory:target reject:reject resolve:resolve];
170+
}
171+
}
172+
173+
RCT_EXPORT_METHOD(snapshot:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
174+
UIImage *image = [[ARKit sharedInstance] getSnaphshot];
175+
[self storeImage:image options:options reject:reject resolve:resolve];
176+
}
177+
178+
179+
180+
181+
RCT_EXPORT_METHOD(snapshotCamera:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
182+
UIImage *image = [[ARKit sharedInstance] getSnaphshotCamera];
183+
[self storeImage:image options:options reject:reject resolve:resolve];
104184
}
105185

106186
RCT_EXPORT_METHOD(getCamera:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {

0 commit comments

Comments
 (0)