Permalink
Browse files

add radial blur overlay when changing blur and cross hair on tap to f…

…ocus.
  • Loading branch information...
1 parent f12fc3e commit 71b79e095171892d535fa7c4e4cae1a75b84aa13 @dmitric committed Nov 19, 2012
View
@@ -0,0 +1,16 @@
+//
+// BlurOverlayView.h
+// Backspaces
+//
+// Created by Dmitri Cherniak on 11/18/12.
+// Copyright (c) 2012 DLC Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface BlurOverlayView : UIView
+
+@property (nonatomic, assign) CGFloat radius;
+@property (nonatomic, assign) CGPoint circleCenter;
+
+@end
View
@@ -0,0 +1,73 @@
+//
+// BlurOverlayView.m
+// Backspaces
+//
+// Created by Dmitri Cherniak on 11/18/12.
+// Copyright (c) 2012 DLC Inc. All rights reserved.
+//
+
+#import "BlurOverlayView.h"
+
+@implementation BlurOverlayView {
+ CGRect holeRect;
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ _radius = 80.0f;
+ // Initialization code
+ self.userInteractionEnabled = NO;
+ self.opaque = NO;
+ CGPoint center = CGPointMake(CGRectGetMidX(frame),CGRectGetMidY(frame));
+ holeRect = CGRectMake(center.x-self.radius, center.y-self.radius, self.radius*2, self.radius*2);
+ }
+ return self;
+}
+
+-(void) setCircleCenter:(CGPoint)circleCenter{
+ _circleCenter = circleCenter;
+ holeRect = CGRectMake(circleCenter.x-self.radius, circleCenter.y-self.radius,
+ self.radius*2,
+ self.radius*2);
+ [self setNeedsDisplay];
+}
+
+-(void) setRadius:(CGFloat)radius{
+ _radius = radius;
+ CGPoint center = CGPointMake(CGRectGetMidX(holeRect),CGRectGetMidY(holeRect));
+ holeRect = CGRectMake(center.x-self.radius, center.y-self.radius,
+ self.radius*2,
+ self.radius*2);
+ [self setNeedsDisplay];
+}
+
+- (void)drawRect:(CGRect)rect {
+ CGContextRef context = UIGraphicsGetCurrentContext();
+
+ size_t numLocations = 2;
+ CGFloat locations[2] = {0.0, 1.0};
+ CGFloat components[8] = {1.0,1.0,1.0, 0.0, // Start color
+ 1.0,1.0,1.0, 0.6 }; // End color
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
+ components,
+ locations,
+ numLocations);
+
+ CGPoint center = CGPointMake(CGRectGetMidX(holeRect),CGRectGetMidY(holeRect));
+
+ CGContextDrawRadialGradient(context, gradient, center,
+ self.radius - 25.0, center, self.radius,
+ kCGGradientDrawsAfterEndLocation);
+
+ CGColorSpaceRelease(colorSpace);
+ CGGradientRelease(gradient);
+
+
+}
+
+
+@end
@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
#import "GPUImage.h"
+#import "BlurOverlayView.h"
@class DLCImagePickerController;
@@ -43,6 +44,8 @@
@property (nonatomic, weak) IBOutlet UIImageView *filtersBackgroundImageView;
@property (nonatomic, weak) IBOutlet UIView *photoBar;
@property (nonatomic, weak) IBOutlet UIView *topBar;
+@property (nonatomic, strong) BlurOverlayView *blurOverlayView;
+@property (nonatomic, strong) UIImageView *focusView;
@property (nonatomic, assign) CGFloat outputJPEGQuality;
@@ -31,6 +31,7 @@ @implementation DLCImagePickerController {
filtersBackgroundImageView,
photoBar,
topBar,
+ blurOverlayView,
outputJPEGQuality;
-(id) init {
@@ -61,6 +62,17 @@ - (void)viewDidLoad
staticPictureOriginalOrientation = UIImageOrientationUp;
+ self.focusView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"focus-crosshair"]];
+ [self.view addSubview:self.focusView];
+ self.focusView.alpha = 0;
+
+
+ self.blurOverlayView = [[BlurOverlayView alloc] initWithFrame:CGRectMake(0, 0,
+ self.imageView.frame.size.width,
+ self.imageView.frame.size.height)];
+ self.blurOverlayView.alpha = 0;
+ [self.imageView addSubview:self.blurOverlayView];
+
hasBlur = NO;
[self loadFilters];
@@ -301,6 +313,7 @@ -(IBAction) toggleBlur:(UIButton*)blurButton {
if (hasBlur) {
hasBlur = NO;
+ [self showBlurOverlay:NO];
[self.blurToggleButton setSelected:NO];
} else {
if (!blurFilter) {
@@ -312,6 +325,7 @@ -(IBAction) toggleBlur:(UIButton*)blurButton {
}
hasBlur = YES;
[self.blurToggleButton setSelected:YES];
+ [self flashBlurOverlay];
}
[self prepareFilter];
@@ -437,21 +451,22 @@ -(IBAction) handlePan:(UIGestureRecognizer *) sender {
(GPUImageGaussianSelectiveBlurFilter*)blurFilter;
if ([sender state] == UIGestureRecognizerStateBegan) {
- //NSLog(@"Start tap");
+ [self showBlurOverlay:YES];
+ [gpu setBlurSize:0.0f];
if (isStatic) {
[staticPicture processImage];
}
}
if ([sender state] == UIGestureRecognizerStateBegan || [sender state] == UIGestureRecognizerStateChanged) {
- //NSLog(@"Moving tap");
- [gpu setBlurSize:5.0f];
+ [gpu setBlurSize:0.0f];
+ [self.blurOverlayView setCircleCenter:tapPoint];
[gpu setExcludeCirclePoint:CGPointMake(tapPoint.x/320.0f, tapPoint.y/320.0f)];
}
if([sender state] == UIGestureRecognizerStateEnded){
[gpu setBlurSize:kStaticBlurSize];
-
+ [self showBlurOverlay:NO];
if (isStatic) {
[staticPicture processImage];
}
@@ -481,6 +496,13 @@ - (IBAction) handleTapToFocus:(UITapGestureRecognizer *)tgr{
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}
+ self.focusView.center = [tgr locationInView:self.view];
+ self.focusView.alpha = 1;
+
+ [UIView animateWithDuration:0.5 delay:0.5 options:0 animations:^{
+ self.focusView.alpha = 0;
+ } completion:nil];
+
[device unlockForConfiguration];
} else {
NSLog(@"ERROR = %@", error);
@@ -496,23 +518,26 @@ -(IBAction) handlePinch:(UIPinchGestureRecognizer *) sender {
(GPUImageGaussianSelectiveBlurFilter*)blurFilter;
if ([sender state] == UIGestureRecognizerStateBegan) {
- //NSLog(@"Start tap");
+ [self showBlurOverlay:YES];
+ [gpu setBlurSize:0.0f];
if (isStatic) {
[staticPicture processImage];
}
}
if ([sender state] == UIGestureRecognizerStateBegan || [sender state] == UIGestureRecognizerStateChanged) {
- [gpu setBlurSize:5.0f];
+ [gpu setBlurSize:0.0f];
[gpu setExcludeCirclePoint:CGPointMake(midpoint.x/320.0f, midpoint.y/320.0f)];
- CGFloat radius = MIN(sender.scale*[gpu excludeCircleRadius], 0.6f);
+ self.blurOverlayView.circleCenter = CGPointMake(midpoint.x, midpoint.y);
+ CGFloat radius = MAX(MIN(sender.scale*[gpu excludeCircleRadius], 0.6f), 0.15f);
+ self.blurOverlayView.radius = radius*320.f;
[gpu setExcludeCircleRadius:radius];
sender.scale = 1.0f;
}
if ([sender state] == UIGestureRecognizerStateEnded) {
[gpu setBlurSize:kStaticBlurSize];
-
+ [self showBlurOverlay:NO];
if (isStatic) {
[staticPicture processImage];
}
@@ -582,13 +607,44 @@ -(IBAction) toggleFilters:(UIButton *)sender {
}
+-(void) showBlurOverlay:(BOOL)show{
+ if(show){
+ [UIView animateWithDuration:0.2 delay:0 options:0 animations:^{
+ self.blurOverlayView.alpha = 0.6;
+ } completion:^(BOOL finished) {
+
+ }];
+ }else{
+ [UIView animateWithDuration:0.35 delay:0.2 options:0 animations:^{
+ self.blurOverlayView.alpha = 0;
+ } completion:^(BOOL finished) {
+
+ }];
+ }
+}
+
+
+-(void) flashBlurOverlay {
+ [UIView animateWithDuration:0.2 delay:0 options:0 animations:^{
+ self.blurOverlayView.alpha = 0.6;
+ } completion:^(BOOL finished) {
+ [UIView animateWithDuration:0.35 delay:0.2 options:0 animations:^{
+ self.blurOverlayView.alpha = 0;
+ } completion:^(BOOL finished) {
+
+ }];
+ }];
+}
+
-(void) dealloc {
[self removeAllTargets];
stillCamera = nil;
cropFilter = nil;
filter = nil;
blurFilter = nil;
staticPicture = nil;
+ self.blurOverlayView = nil;
+ self.focusView = nil;
}
- (void)viewWillDisappear:(BOOL)animated {
@@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
+ 6A0D0A01165A1CBE0028E1B6 /* BlurOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D0A00165A1CBE0028E1B6 /* BlurOverlayView.m */; };
+ 6A0D0A0F165A1FFC0028E1B6 /* focus-crosshair.png in Resources */ = {isa = PBXBuildFile; fileRef = 6A0D0A0D165A1FFC0028E1B6 /* focus-crosshair.png */; };
+ 6A0D0A10165A1FFC0028E1B6 /* focus-crosshair@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6A0D0A0E165A1FFC0028E1B6 /* focus-crosshair@2x.png */; };
6A23390E15E6C17000CC6CB2 /* library@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6A23390C15E6C17000CC6CB2 /* library@2x.png */; };
6A23390F15E6C17000CC6CB2 /* library.png in Resources */ = {isa = PBXBuildFile; fileRef = 6A23390D15E6C17000CC6CB2 /* library.png */; };
6A42CF7615E46F0E0062D3E7 /* blur-on.png in Resources */ = {isa = PBXBuildFile; fileRef = 6A42CF7415E46F0E0062D3E7 /* blur-on.png */; };
@@ -113,6 +116,10 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 6A0D09FF165A1CBE0028E1B6 /* BlurOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlurOverlayView.h; sourceTree = "<group>"; };
+ 6A0D0A00165A1CBE0028E1B6 /* BlurOverlayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlurOverlayView.m; sourceTree = "<group>"; };
+ 6A0D0A0D165A1FFC0028E1B6 /* focus-crosshair.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "focus-crosshair.png"; sourceTree = "<group>"; };
+ 6A0D0A0E165A1FFC0028E1B6 /* focus-crosshair@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "focus-crosshair@2x.png"; sourceTree = "<group>"; };
6A23390C15E6C17000CC6CB2 /* library@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "library@2x.png"; sourceTree = "<group>"; };
6A23390D15E6C17000CC6CB2 /* library.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = library.png; sourceTree = "<group>"; };
6A42CF7415E46F0E0062D3E7 /* blur-on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "blur-on.png"; sourceTree = "<group>"; };
@@ -319,6 +326,8 @@
6A5D9A8515E02429001FAD14 /* Classes */ = {
isa = PBXGroup;
children = (
+ 6A0D09FF165A1CBE0028E1B6 /* BlurOverlayView.h */,
+ 6A0D0A00165A1CBE0028E1B6 /* BlurOverlayView.m */,
7D0E5AB515E20987009D19C9 /* Filters */,
6A5D9A8915E02504001FAD14 /* PhotoViewController.h */,
6A5D9A8A15E02504001FAD14 /* PhotoViewController.m */,
@@ -351,6 +360,8 @@
6A5D9A9515E02527001FAD14 /* UI */ = {
isa = PBXGroup;
children = (
+ 6A0D0A0D165A1FFC0028E1B6 /* focus-crosshair.png */,
+ 6A0D0A0E165A1FFC0028E1B6 /* focus-crosshair@2x.png */,
6A23390C15E6C17000CC6CB2 /* library@2x.png */,
6A23390D15E6C17000CC6CB2 /* library.png */,
6A42CF7415E46F0E0062D3E7 /* blur-on.png */,
@@ -566,6 +577,8 @@
6A5530BA15E486E900019CC9 /* 10@2x.jpg in Resources */,
6A23390E15E6C17000CC6CB2 /* library@2x.png in Resources */,
6A23390F15E6C17000CC6CB2 /* library.png in Resources */,
+ 6A0D0A0F165A1FFC0028E1B6 /* focus-crosshair.png in Resources */,
+ 6A0D0A10165A1FFC0028E1B6 /* focus-crosshair@2x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -581,6 +594,7 @@
6A5D9A8815E02429001FAD14 /* DLCImagePickerController.m in Sources */,
6A5D9A8B15E02504001FAD14 /* PhotoViewController.m in Sources */,
7D0E5AB815E209AD009D19C9 /* GrayscaleContrastFilter.m in Sources */,
+ 6A0D0A01165A1CBE0028E1B6 /* BlurOverlayView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 71b79e0

Please sign in to comment.