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
// | |
// 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 |
// | |
// 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