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
Patrick Piemonte committed Sep 5, 2013

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 17eb875 commit 0080a32
Showing 10 changed files with 494 additions and 41 deletions.
7 changes: 4 additions & 3 deletions PBJVision.podspec
Original file line number Diff line number Diff line change
@@ -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" => "[email protected]" }
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
Original file line number Diff line number Diff line change
@@ -14,6 +14,12 @@
060F7B19179F50B800E27091 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B15179F50B800E27091 /* [email protected] */; };
060F7B1A179F50B800E27091 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B16179F50B800E27091 /* [email protected] */; };
060F7B1D179F550800E27091 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 060F7B1C179F550800E27091 /* [email protected] */; };
0624D09717D43BB500665930 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 0624D09517D43BB500665930 /* [email protected] */; };
0624D09817D43BB500665930 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 0624D09617D43BB500665930 /* [email protected] */; };
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 */; };
@@ -45,6 +51,12 @@
060F7B15179F50B800E27091 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "UI/[email protected]"; sourceTree = "<group>"; };
060F7B16179F50B800E27091 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "UI/[email protected]"; sourceTree = "<group>"; };
060F7B1C179F550800E27091 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "UI/[email protected]"; sourceTree = "<group>"; };
0624D09517D43BB500665930 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "UI/[email protected]"; sourceTree = "<group>"; };
0624D09617D43BB500665930 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "[email protected]"; path = "UI/[email protected]"; 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; };
@@ -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 */,
@@ -102,10 +116,21 @@
060F7B15179F50B800E27091 /* [email protected] */,
060F7B16179F50B800E27091 /* [email protected] */,
060F7B1C179F550800E27091 /* [email protected] */,
0624D09517D43BB500665930 /* [email protected] */,
0624D09617D43BB500665930 /* [email protected] */,
);
name = UI;
sourceTree = "<group>";
};
067D52F917D8577D00541B5E /* Shaders */ = {
isa = PBXGroup;
children = (
067D52FA17D857AB00541B5E /* Shader.fsh */,
067D52FB17D857AB00541B5E /* Shader.vsh */,
);
name = Shaders;
sourceTree = "<group>";
};
0683D1B5179F2E1700EE66D6 = {
isa = PBXGroup;
children = (
@@ -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;
@@ -176,6 +203,7 @@
06B7D026179F2F0800F3F527 /* Vision */ = {
isa = PBXGroup;
children = (
067D52F917D8577D00541B5E /* Shaders */,
06B7D01A179F2E7700F3F527 /* PBJVision.h */,
06B7D01B179F2E7700F3F527 /* PBJVision.m */,
06B7D01C179F2E7700F3F527 /* PBJVisionUtilities.h */,
@@ -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 /* [email protected] in Resources */,
0624D09717D43BB500665930 /* [email protected] in Resources */,
06B7D036179F357600F3F527 /* Default.png in Resources */,
0683D1CC179F2E1700EE66D6 /* InfoPlist.strings in Resources */,
060F7B17179F50B800E27091 /* [email protected] in Resources */,
@@ -249,6 +280,7 @@
06B7D037179F357600F3F527 /* [email protected] in Resources */,
060F7B19179F50B800E27091 /* [email protected] in Resources */,
06B7D024179F2EDC00F3F527 /* Debug.xcconfig in Resources */,
0624D09817D43BB500665930 /* [email protected] in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
70 changes: 42 additions & 28 deletions Project/Vision/PBJViewController.m
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
#import "PBJStrobeView.h"

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

@interface UIButton (ExtendedHit)

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

UIButton *_flipButton;
UIButton *_onionButton;

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

UILabel *_instructionLabel;

UILongPressGestureRecognizer *_longPressGestureRecognizer;
@@ -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;
@@ -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
@@ -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
@@ -218,6 +234,7 @@ - (void)_resetCapture
[vision setCameraDevice:PBJCameraDeviceBack];
[vision setCameraOrientation:PBJCameraOrientationPortrait];
[vision setFocusMode:PBJFocusModeAutoFocus];
[vision setVideoRenderingEnabled:YES];
}

#pragma mark - UIButton
@@ -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
@@ -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
{
}
Binary file added Project/Vision/UI/[email protected]
Loading
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/[email protected]
Loading
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@ extern NSString * const PBJVisionPhotoThumbnailKey; // 160x120
extern NSString * const PBJVisionVideoPathKey;
extern NSString * const PBJVisionVideoThumbnailKey;

@class EAGLContext;
@protocol PBJVisionDelegate;
@interface PBJVision : NSObject
{
@@ -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;
377 changes: 374 additions & 3 deletions Source/PBJVision.m

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions Source/Shaders/Shader.fsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

uniform sampler2D u_samplerY;
uniform sampler2D u_samplerUV;

varying highp vec2 v_texture;

void main()
{
mediump vec3 yuv;
lowp vec3 rgb;

yuv.x = texture2D(u_samplerY, v_texture).r;
yuv.yz = texture2D(u_samplerUV, v_texture).rg - vec2(0.5, 0.5);

// BT.709, the standard for HDTV
rgb = mat3( 1, 1, 1,
0, -.18732, 1.8556,
1.57481, -.46813, 0) * yuv;

gl_FragColor = vec4(rgb, 1);
}

11 changes: 11 additions & 0 deletions Source/Shaders/Shader.vsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

attribute vec4 a_position;
attribute vec2 a_texture;

varying vec2 v_texture;

void main()
{
v_texture = a_texture;
gl_Position = a_position;
}

0 comments on commit 0080a32

Please sign in to comment.