-
-
Save loopspace/0109f800c5766dfccc0501394db6d299 to your computer and use it in GitHub Desktop.
A Codea addon for saving images to the photo album, share photos to facebook and detect faces in an image. Just add [self.viewController registerAddon:[ImageTools sharedInstance]]; to AppDelegate.mm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ImageTools.h | |
// FaceDetection | |
// | |
// Created by Tobias Teleman on fredag 12 april 2013 | |
// Copyright (c) Tobias Teleman. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#import "CodeaAddon.h" | |
#define DEFINE_SHARED_INSTANCE_USING_BLOCK(block) \ | |
+ (instancetype)sharedInstance\ | |
{\ | |
static dispatch_once_t pred = 0; \ | |
__strong static id _sharedObject = nil; \ | |
dispatch_once(&pred, ^{ \ | |
_sharedObject = block(); \ | |
}); \ | |
return _sharedObject; \ | |
}\ | |
#define DEFINE_SHARED_INSTANCE \ | |
+ (instancetype)sharedInstance;\ | |
#define DEFINE_SHARED_INSTANCE_IMPL \ | |
DEFINE_SHARED_INSTANCE_USING_BLOCK(^{\ | |
return [[self alloc] init];\ | |
})\ | |
@interface ImageTools: NSObject<CodeaAddon> | |
DEFINE_SHARED_INSTANCE | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ImageTools.mm | |
// FaceDetection | |
// | |
// Created by Tobias Teleman on fredag 12 april 2013 | |
// Copyright (c) Tobias Teleman. All rights reserved. | |
// | |
#import "ImageTools.h" | |
#import "Social/Social.h" | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#import "lua.h" | |
#import "lauxlib.h" | |
struct image_type_t; | |
struct image_type_t *checkimage(lua_State *L, int i); | |
typedef enum PersistenceImageAlpha | |
{ | |
PersistenceImageAlphaPremultiply, | |
PersistenceImageAlphaNoPremultiply, | |
} PersistenceImageAlpha; | |
UIImage* createUIImageFromImage(struct image_type_t* image, PersistenceImageAlpha alphaOption); | |
#ifdef __cplusplus | |
} | |
#endif | |
static int WriteToPhotoAlbumFunction(struct lua_State *state); | |
static int ShareToFacebook(struct lua_State *state); | |
static int DetectFaceFeatures(struct lua_State *state); | |
@interface ImageTools() | |
@property (nonatomic, weak) CodeaViewController *codeaViewController; | |
@property (nonatomic, strong) CIDetector* detector; | |
@end | |
@implementation ImageTools | |
DEFINE_SHARED_INSTANCE_IMPL | |
- (void) codea:(CodeaViewController*)controller didCreateLuaState:(struct lua_State*)L | |
{ | |
NSLog(@"Register ImageTools"); | |
self.codeaViewController = controller; | |
lua_register(L, "saveToPhotoAlbum", WriteToPhotoAlbumFunction); | |
lua_register(L, "shareToFacebook", ShareToFacebook); | |
lua_register(L, "detectFaceFeatures", DetectFaceFeatures); | |
NSDictionary *detectorOptions = [[NSDictionary alloc] initWithObjectsAndKeys:CIDetectorAccuracyLow, CIDetectorAccuracy, nil]; | |
self.detector = [CIDetector detectorOfType:CIDetectorTypeFace | |
context:nil options:detectorOptions]; | |
} | |
@end | |
static int WriteToPhotoAlbumFunction(struct lua_State *state) { | |
struct image_type_t* imageType = checkimage(state, 1); | |
UIImage* image = createUIImageFromImage(imageType, PersistenceImageAlphaNoPremultiply); | |
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); | |
return 0; | |
} | |
static int ShareToFacebook(struct lua_State *state) { | |
SLComposeViewController *fbController=[SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook]; | |
struct image_type_t* imageType = checkimage(state, 1); | |
UIImage* image = createUIImageFromImage(imageType, PersistenceImageAlphaNoPremultiply); | |
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) | |
{ | |
SLComposeViewControllerCompletionHandler __block completionHandler=^(SLComposeViewControllerResult result){ | |
[fbController dismissViewControllerAnimated:YES completion:nil]; | |
switch(result){ | |
case SLComposeViewControllerResultCancelled: | |
default: | |
{ | |
NSLog(@"Cancelled"); | |
} | |
break; | |
case SLComposeViewControllerResultDone: | |
{ | |
NSLog(@"Posted"); | |
} | |
break; | |
}}; | |
[fbController addImage:image]; | |
[fbController setInitialText:@"I made this with Recursive!"]; | |
[fbController setCompletionHandler:completionHandler]; | |
[[ImageTools sharedInstance].codeaViewController | |
presentViewController:fbController animated:YES completion:nil]; | |
} | |
return 0; | |
} | |
static int DetectFaceFeatures(struct lua_State *state) { | |
struct image_type_t* imageType = checkimage(state, 1); | |
UIImage* image = createUIImageFromImage(imageType, PersistenceImageAlphaNoPremultiply); | |
CIImage* ciimage = [CIImage imageWithCGImage:image.CGImage]; | |
NSArray* features = [[ImageTools sharedInstance].detector featuresInImage:ciimage]; | |
for(CIFaceFeature* faceFeature in features) { | |
lua_newtable(state); | |
lua_pushstring(state, "x"); | |
lua_pushinteger(state, faceFeature.bounds.origin.x); | |
lua_settable(state, -3); | |
lua_pushstring(state, "y"); | |
lua_pushinteger(state, faceFeature.bounds.origin.y); | |
lua_settable(state, -3); | |
lua_pushstring(state, "width"); | |
lua_pushinteger(state, faceFeature.bounds.size.width); | |
lua_settable(state, -3); | |
lua_pushstring(state, "height"); | |
lua_pushinteger(state, faceFeature.bounds.size.height); | |
lua_settable(state, -3); | |
if(faceFeature.hasLeftEyePosition) { | |
lua_pushstring(state, "leftEye"); | |
lua_newtable(state); | |
lua_pushstring(state, "x"); | |
lua_pushinteger(state, faceFeature.leftEyePosition.x); | |
lua_settable(state, -3); | |
lua_pushstring(state, "y"); | |
lua_pushinteger(state, faceFeature.leftEyePosition.y); | |
lua_settable(state, -3); | |
lua_settable(state, -3); | |
} | |
if(faceFeature.hasRightEyePosition) { | |
lua_pushstring(state, "rightEye"); | |
lua_newtable(state); | |
lua_pushstring(state, "x"); | |
lua_pushinteger(state, faceFeature.rightEyePosition.x); | |
lua_settable(state, -3); | |
lua_pushstring(state, "y"); | |
lua_pushinteger(state, faceFeature.rightEyePosition.y); | |
lua_settable(state, -3); | |
lua_settable(state, -3); | |
} | |
if(faceFeature.hasMouthPosition) { | |
lua_pushstring(state, "mouth"); | |
lua_newtable(state); | |
lua_pushstring(state, "x"); | |
lua_pushinteger(state, faceFeature.mouthPosition.x); | |
lua_settable(state, -3); | |
lua_pushstring(state, "y"); | |
lua_pushinteger(state, faceFeature.mouthPosition.y); | |
lua_settable(state, -3); | |
lua_settable(state, -3); | |
} | |
return 1; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment