Skip to content
This repository has been archived by the owner on Mar 7, 2023. It is now read-only.

Commit

Permalink
PBJVision: onion skinning (ghosting), fixes GH-1
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Piemonte committed Sep 5, 2013
1 parent 17eb875 commit 0080a32
Show file tree
Hide file tree
Showing 10 changed files with 494 additions and 41 deletions.
7 changes: 4 additions & 3 deletions PBJVision.podspec
@@ -1,13 +1,14 @@
Pod::Spec.new do |s|
s.name = "PBJVision"
s.version = "0.1.1"
s.version = "0.1.2"
s.summary = "iOS camera engine, supports touch-to-record video and photo capture."
s.homepage = "https://github.com/piemonte/PBJVision"
s.license = "MIT"
s.authors = { "Patrick Piemonte" => "piemonte@alumni.cmu.edu" }
s.source = { :git => "https://github.com/piemonte/PBJVision.git", :tag => "v0.1.1" }
s.frameworks = 'Foundation', 'AVFoundation', 'CoreGraphics', 'CoreMedia', 'CoreVideo', 'MobileCoreServices', 'ImageIO', 'QuartzCore'
s.source = { :git => "https://github.com/piemonte/PBJVision.git", :tag => "v0.1.2" }
s.frameworks = 'Foundation', 'AVFoundation', 'CoreGraphics', 'CoreMedia', 'CoreVideo', 'MobileCoreServices', 'ImageIO', 'QuartzCore', 'OpenGLES', 'UIKit'
s.platform = :ios, '6.0'
s.source_files = 'Source'
s.resources = 'Source/Shaders/*'
s.requires_arc = true
end
42 changes: 37 additions & 5 deletions Project/Vision.xcodeproj/project.pbxproj
Expand Up @@ -14,6 +14,12 @@
060F7B19179F50B800E27091 /* capture_rec_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B15179F50B800E27091 /* capture_rec_off@2x.png */; };
060F7B1A179F50B800E27091 /* capture_yep@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B16179F50B800E27091 /* capture_yep@2x.png */; };
060F7B1D179F550800E27091 /* capture_flip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B1C179F550800E27091 /* capture_flip@2x.png */; };
0624D09717D43BB500665930 /* capture_onion_selected@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0624D09517D43BB500665930 /* capture_onion_selected@2x.png */; };
0624D09817D43BB500665930 /* capture_onion@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0624D09617D43BB500665930 /* capture_onion@2x.png */; };
0624D09A17D43D5D00665930 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0624D09917D43D5D00665930 /* OpenGLES.framework */; };
067D52F817D8574200541B5E /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 067D52F717D8574200541B5E /* GLKit.framework */; };
067D52FC17D857DC00541B5E /* Shader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 067D52FA17D857AB00541B5E /* Shader.fsh */; };
067D52FD17D857DC00541B5E /* Shader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 067D52FB17D857AB00541B5E /* Shader.vsh */; };
0683D1C2179F2E1700EE66D6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0683D1C1179F2E1700EE66D6 /* Foundation.framework */; };
0683D1C4179F2E1700EE66D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0683D1C3179F2E1700EE66D6 /* CoreGraphics.framework */; };
0683D1C6179F2E1700EE66D6 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0683D1C5179F2E1700EE66D6 /* UIKit.framework */; };
Expand Down Expand Up @@ -45,6 +51,12 @@
060F7B15179F50B800E27091 /* capture_rec_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "capture_rec_off@2x.png"; path = "UI/capture_rec_off@2x.png"; sourceTree = "<group>"; };
060F7B16179F50B800E27091 /* capture_yep@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "capture_yep@2x.png"; path = "UI/capture_yep@2x.png"; sourceTree = "<group>"; };
060F7B1C179F550800E27091 /* capture_flip@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "capture_flip@2x.png"; path = "UI/capture_flip@2x.png"; sourceTree = "<group>"; };
0624D09517D43BB500665930 /* capture_onion_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "capture_onion_selected@2x.png"; path = "UI/capture_onion_selected@2x.png"; sourceTree = "<group>"; };
0624D09617D43BB500665930 /* capture_onion@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "capture_onion@2x.png"; path = "UI/capture_onion@2x.png"; sourceTree = "<group>"; };
0624D09917D43D5D00665930 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
067D52F717D8574200541B5E /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
067D52FA17D857AB00541B5E /* Shader.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.fsh; path = ../Source/Shaders/Shader.fsh; sourceTree = "<group>"; };
067D52FB17D857AB00541B5E /* Shader.vsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Shader.vsh; path = ../Source/Shaders/Shader.vsh; sourceTree = "<group>"; };
0683D1BE179F2E1700EE66D6 /* Vision.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Vision.app; sourceTree = BUILT_PRODUCTS_DIR; };
0683D1C1179F2E1700EE66D6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
0683D1C3179F2E1700EE66D6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -79,6 +91,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
067D52F817D8574200541B5E /* GLKit.framework in Frameworks */,
0624D09A17D43D5D00665930 /* OpenGLES.framework in Frameworks */,
060F7B0F179F459900E27091 /* AssetsLibrary.framework in Frameworks */,
06B7D031179F33B500F3F527 /* ImageIO.framework in Frameworks */,
06B7D02F179F333400F3F527 /* MobileCoreServices.framework in Frameworks */,
Expand All @@ -102,10 +116,21 @@
060F7B15179F50B800E27091 /* capture_rec_off@2x.png */,
060F7B16179F50B800E27091 /* capture_yep@2x.png */,
060F7B1C179F550800E27091 /* capture_flip@2x.png */,
0624D09517D43BB500665930 /* capture_onion_selected@2x.png */,
0624D09617D43BB500665930 /* capture_onion@2x.png */,
);
name = UI;
sourceTree = "<group>";
};
067D52F917D8577D00541B5E /* Shaders */ = {
isa = PBXGroup;
children = (
067D52FA17D857AB00541B5E /* Shader.fsh */,
067D52FB17D857AB00541B5E /* Shader.vsh */,
);
name = Shaders;
sourceTree = "<group>";
};
0683D1B5179F2E1700EE66D6 = {
isa = PBXGroup;
children = (
Expand All @@ -128,13 +153,15 @@
isa = PBXGroup;
children = (
060F7B0E179F459900E27091 /* AssetsLibrary.framework */,
06B7D030179F33B500F3F527 /* ImageIO.framework */,
06B7D02D179F330E00F3F527 /* MobileCoreServices.framework */,
06B7D02B179F313800F3F527 /* CoreVideo.framework */,
06B7D029179F312F00F3F527 /* CoreMedia.framework */,
06B7D027179F307D00F3F527 /* AVFoundation.framework */,
0683D1C1179F2E1700EE66D6 /* Foundation.framework */,
0683D1C3179F2E1700EE66D6 /* CoreGraphics.framework */,
06B7D029179F312F00F3F527 /* CoreMedia.framework */,
06B7D02B179F313800F3F527 /* CoreVideo.framework */,
0683D1C1179F2E1700EE66D6 /* Foundation.framework */,
067D52F717D8574200541B5E /* GLKit.framework */,
06B7D030179F33B500F3F527 /* ImageIO.framework */,
06B7D02D179F330E00F3F527 /* MobileCoreServices.framework */,
0624D09917D43D5D00665930 /* OpenGLES.framework */,
0683D1C5179F2E1700EE66D6 /* UIKit.framework */,
);
name = Frameworks;
Expand Down Expand Up @@ -176,6 +203,7 @@
06B7D026179F2F0800F3F527 /* Vision */ = {
isa = PBXGroup;
children = (
067D52F917D8577D00541B5E /* Shaders */,
06B7D01A179F2E7700F3F527 /* PBJVision.h */,
06B7D01B179F2E7700F3F527 /* PBJVision.m */,
06B7D01C179F2E7700F3F527 /* PBJVisionUtilities.h */,
Expand Down Expand Up @@ -237,8 +265,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
067D52FC17D857DC00541B5E /* Shader.fsh in Resources */,
067D52FD17D857DC00541B5E /* Shader.vsh in Resources */,
06B7D025179F2EDC00F3F527 /* Release.xcconfig in Resources */,
060F7B18179F50B800E27091 /* capture_rec_blink@2x.png in Resources */,
0624D09717D43BB500665930 /* capture_onion_selected@2x.png in Resources */,
06B7D036179F357600F3F527 /* Default.png in Resources */,
0683D1CC179F2E1700EE66D6 /* InfoPlist.strings in Resources */,
060F7B17179F50B800E27091 /* capture_rec_base@2x.png in Resources */,
Expand All @@ -249,6 +280,7 @@
06B7D037179F357600F3F527 /* Default@2x.png in Resources */,
060F7B19179F50B800E27091 /* capture_rec_off@2x.png in Resources */,
06B7D024179F2EDC00F3F527 /* Debug.xcconfig in Resources */,
0624D09817D43BB500665930 /* capture_onion@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
70 changes: 42 additions & 28 deletions Project/Vision/PBJViewController.m
Expand Up @@ -11,6 +11,7 @@
#import "PBJStrobeView.h"

#import <AssetsLibrary/AssetsLibrary.h>
#import <GLKit/GLKit.h>

@interface UIButton (ExtendedHit)

Expand All @@ -37,10 +38,14 @@ @interface PBJViewController () <
{
PBJStrobeView *_strobeView;
UIButton *_doneButton;

UIButton *_flipButton;
UIButton *_onionButton;

UIView *_previewView;
AVCaptureVideoPreviewLayer *_previewLayer;
GLKViewController *_effectsViewController;

UILabel *_instructionLabel;

UILongPressGestureRecognizer *_longPressGestureRecognizer;
Expand Down Expand Up @@ -99,21 +104,28 @@ - (void)_setup
// preview
_previewView = [[UIView alloc] initWithFrame:CGRectZero];
_previewView.backgroundColor = [UIColor blackColor];
CGRect previewFrame = CGRectZero;
previewFrame.origin = CGPointMake(0, 60.0f);
CGFloat previewWidth = self.view.frame.size.width;
previewFrame.size = CGSizeMake(previewWidth, previewWidth);
CGRect previewFrame = CGRectMake(0, 60.0f, CGRectGetWidth(self.view.frame), CGRectGetWidth(self.view.frame));
_previewView.frame = previewFrame;

// add AV layer
_previewLayer = [[PBJVision sharedInstance] previewLayer];
CGRect previewBounds = _previewView.layer.bounds;
_previewLayer.bounds = previewBounds;
_previewLayer.frame = _previewView.bounds;
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.position = CGPointMake(CGRectGetMidX(previewBounds), CGRectGetMidY(previewBounds));
[_previewView.layer addSublayer:_previewLayer];
[self.view addSubview:_previewView];

// onion skin
_effectsViewController = [[GLKViewController alloc] init];
_effectsViewController.preferredFramesPerSecond = 60;

GLKView *view = (GLKView *)_effectsViewController.view;
CGRect viewFrame = _previewView.bounds;
view.frame = viewFrame;
view.context = [[PBJVision sharedInstance] context];
view.contentScaleFactor = [[UIScreen mainScreen] scale];
view.alpha = 0.5f;
view.hidden = YES;
[[PBJVision sharedInstance] setPresentationFrame:_previewView.frame];
[_previewView addSubview:_effectsViewController.view];

// instruction label
_instructionLabel = [[UILabel alloc] initWithFrame:self.view.bounds];
_instructionLabel.textAlignment = NSTextAlignmentCenter;
Expand Down Expand Up @@ -145,17 +157,18 @@ - (void)_setup

// flip button
_flipButton = [UIButton buttonWithType:UIButtonTypeCustom];

UIImage *flipImage = [UIImage imageNamed:@"capture_flip"];
[_flipButton setImage:flipImage forState:UIControlStateNormal];

CGRect flipFrame = _flipButton.frame;
flipFrame.size = CGSizeMake(25.0f, 20.0f);
flipFrame.origin = CGPointMake(10.0f, CGRectGetHeight(self.view.bounds) - 10.0f);
_flipButton.frame = flipFrame;

[_flipButton setImage:[UIImage imageNamed:@"capture_flip"] forState:UIControlStateNormal];
_flipButton.frame = CGRectMake(15.0f, CGRectGetHeight(self.view.bounds) - 15.0f, 30.0f, 25.0f);
[_flipButton addTarget:self action:@selector(_handleFlipButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_flipButton];

// onion button
_onionButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_onionButton setImage:[UIImage imageNamed:@"capture_onion"] forState:UIControlStateNormal];
[_onionButton setImage:[UIImage imageNamed:@"capture_onion_selected"] forState:UIControlStateSelected];
_onionButton.frame = CGRectMake(CGRectGetWidth(self.view.bounds) - 25.0f - 15.0f, CGRectGetHeight(self.view.bounds) - 15.0f, 25.0f, 25.0f);
[_onionButton addTarget:self action:@selector(_handleOnionSkinningButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_onionButton];
}

#pragma mark - view lifecycle
Expand Down Expand Up @@ -194,17 +207,20 @@ - (void)_startCapture
- (void)_pauseCapture
{
[[PBJVision sharedInstance] pauseVideoCapture];
_effectsViewController.view.hidden = !_onionButton.selected;
}

- (void)_resumeCapture
{
[[PBJVision sharedInstance] resumeVideoCapture];
_effectsViewController.view.hidden = YES;
}

- (void)_endCapture
{
[UIApplication sharedApplication].idleTimerDisabled = NO;
[[PBJVision sharedInstance] endVideoCapture];
_effectsViewController.view.hidden = YES;
}

- (void)_resetCapture
Expand All @@ -218,6 +234,7 @@ - (void)_resetCapture
[vision setCameraDevice:PBJCameraDeviceBack];
[vision setCameraOrientation:PBJCameraOrientationPortrait];
[vision setFocusMode:PBJFocusModeAutoFocus];
[vision setVideoRenderingEnabled:YES];
}

#pragma mark - UIButton
Expand All @@ -232,6 +249,13 @@ - (void)_handleFlipButton:(UIButton *)button
}
}

- (void)_handleOnionSkinningButton:(UIButton *)button
{
[_onionButton setSelected:!_onionButton.selected];
if (_recording)
_effectsViewController.view.hidden = !_onionButton.selected;
}

- (void)_handleDoneButton:(UIButton *)button
{
// resets long press
Expand Down Expand Up @@ -287,16 +311,6 @@ - (void)visionSessionDidStop:(PBJVision *)vision
{
}

- (void)visionPreviewDidStart:(PBJVision *)vision
{
_longPressGestureRecognizer.enabled = YES;
}

- (void)visionPreviewWillStop:(PBJVision *)vision
{
_longPressGestureRecognizer.enabled = NO;
}

- (void)visionModeWillChange:(PBJVision *)vision
{
}
Expand Down
Binary file added Project/Vision/UI/capture_onion@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Project/Vision/UI/capture_onion_selected@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions Project/Vision/Vision-Info.plist
Expand Up @@ -31,8 +31,6 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
4 changes: 4 additions & 0 deletions Source/PBJVision.h
Expand Up @@ -45,6 +45,7 @@ extern NSString * const PBJVisionPhotoThumbnailKey; // 160x120
extern NSString * const PBJVisionVideoPathKey;
extern NSString * const PBJVisionVideoThumbnailKey;

@class EAGLContext;
@protocol PBJVisionDelegate;
@interface PBJVision : NSObject
{
Expand Down Expand Up @@ -89,6 +90,9 @@ extern NSString * const PBJVisionVideoThumbnailKey;
@property (nonatomic, readonly) BOOL supportsVideoCapture;
@property (nonatomic, readonly) BOOL canCaptureVideo;

@property (nonatomic, getter=isVideoRenderingEnabled) BOOL videoRenderingEnabled;
@property (nonatomic, readonly) EAGLContext *context;
@property (nonatomic) CGRect presentationFrame;

- (void)startVideoCapture;
- (void)pauseVideoCapture;
Expand Down

0 comments on commit 0080a32

Please sign in to comment.