Touch Moved Method in our View Controller
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { if (TouchEnable) { UITouch *touch = [touches anyObject]; CGPoint touchPoint = [touch locationInView:_img_view]; @autoreleasepool { double dx = fabs(BeginPoint.x - touchPoint.x); double dy = fabs(BeginPoint.y - touchPoint.y); double dist = sqrt(dx*dx + dy*dy); // NSLog(@"%f Dist: %f",fabs(BeginPoint.x - touchPoint.x),dist); if (dist > 20) { [self RemoveMemory]; sourcePicture = [[GPUImagePicture alloc] initWithImage:_img_view.image]; filter = [[GPUImageFilterCustom alloc] init]; [filter useNextFrameForImageCapture]; [sourcePicture addTarget:filter]; double X = (touchPoint.x/_img_view.frame.size.width); double Y = (touchPoint.y/_img_view.frame.size.height); [(GPUImageFilterCustom *)filter setCenter:CGPointMake(X, Y)]; [(GPUImageFilterCustom *)filter setRadius:0.09]; [(GPUImageFilterCustom *)filter setScale:0.05]; double XX = 0.0, YY = 0.0; if (touchPoint.x - BeginPoint.x > 0) { //finger touch went right XX = -1.0; } else if (touchPoint.x - BeginPoint.x != 0) { //finger touch went left XX = 1.0; } if (touchPoint.y - BeginPoint.y > 0) { //finger touch went upwards YY = -1.0; } else if (touchPoint.y - BeginPoint.y != 0) { //finger touch went downwards YY = 1.0; } [(GPUImageFilterCustom *)filter setDirection:CGPointMake(XX, YY)]; [sourcePicture processImage]; _img_view.image = [filter imageFromCurrentFramebuffer]; BeginPoint = touchPoint; } } } }
Filter.h
#import <GPUImage/GPUImage.h> /** Creates a swirl distortion on the image */ @interface GPUImageFilterCustom : GPUImageFilter { GLint aspectRatioUniform, radiusUniform, centerUniform, scaleUniform, directionUniform; } /** The center about which to apply the distortion, with a default of (0.5, 0.5) */ @property(readwrite, nonatomic) CGPoint center; /** The radius of the distortion, ranging from 0.0 to 2.0, with a default of 1.0 */ @property(readwrite, nonatomic) CGFloat radius; /** The amount of distortion to apply, from -2.0 to 2.0, with a default of 0.5 */ @property(readwrite, nonatomic) CGFloat scale; /** The amount of distortion to apply, from -1.0 to 1.0, with a default of 0.5 */ @property(readwrite, nonatomic) CGPoint direction; @end
Filter.m
#import "GPUImageFilterCustom.h" #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE NSString *const kGPUImagePinchCoustomShaderString = SHADER_STRING ( varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform highp float aspectRatio; uniform highp vec2 center; uniform highp float radius; uniform highp float scale; uniform highp vec2 direction; void main() { highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); highp float dist = distance(center, textureCoordinateToUse); textureCoordinateToUse = textureCoordinate; if (dist < radius) { textureCoordinateToUse -= center; highp float gVal = exp(-(pow((dist/radius),2.0) * 2.0)) * 0.2; highp float percent = clamp(1.0 - dist/radius,0.0,1.0)*scale * 0.8; textureCoordinateToUse += direction * percent * gVal ; textureCoordinateToUse += center; gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); } else { gl_FragColor = texture2D(inputImageTexture, textureCoordinate ); } } ); #else NSString *const kGPUImagePinchCoustomShaderString = SHADER_STRING ( varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; uniform float aspectRatio; uniform vec2 center; uniform float radius; uniform float scale; void main() { vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); float dist = distance(center, textureCoordinateToUse); textureCoordinateToUse = textureCoordinate; if (dist < radius) { textureCoordinateToUse -= center; float percent = 1.0 + ((0.5 - dist) / 0.5) * scale; textureCoordinateToUse = textureCoordinateToUse * percent; textureCoordinateToUse += center; gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse ); } else { gl_FragColor = texture2D(inputImageTexture, textureCoordinate ); } } ); #endif @interface GPUImageFilterCustom () - (void)adjustAspectRatio; @property (readwrite, nonatomic) CGFloat aspectRatio; @end @implementation GPUImageFilterCustom @synthesize aspectRatio = _aspectRatio; @synthesize center = _center; @synthesize radius = _radius; @synthesize scale = _scale; @synthesize direction = _direction; #pragma mark - #pragma mark Initialization and teardown - (id)init; { if (!(self = [super initWithFragmentShaderFromString:kGPUImagePinchCoustomShaderString])) { return nil; } directionUniform = [filterProgram uniformIndex:@"direction"]; aspectRatioUniform = [filterProgram uniformIndex:@"aspectRatio"]; radiusUniform = [filterProgram uniformIndex:@"radius"]; scaleUniform = [filterProgram uniformIndex:@"scale"]; centerUniform = [filterProgram uniformIndex:@"center"]; self.radius = 1.0; self.scale = 0.5; self.center = CGPointMake(0.5, 0.5); self.direction = CGPointMake(0.0, 0.0); return self; } #pragma mark - #pragma mark Accessors - (void)adjustAspectRatio; { if (GPUImageRotationSwapsWidthAndHeight(inputRotation)) { [self setAspectRatio:(inputTextureSize.width / inputTextureSize.height)]; } else { [self setAspectRatio:(inputTextureSize.height / inputTextureSize.width)]; } } - (void)forceProcessingAtSize:(CGSize)frameSize; { [super forceProcessingAtSize:frameSize]; [self adjustAspectRatio]; } - (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex; { CGSize oldInputSize = inputTextureSize; [super setInputSize:newSize atIndex:textureIndex]; if ( (!CGSizeEqualToSize(oldInputSize, inputTextureSize)) && (!CGSizeEqualToSize(newSize, CGSizeZero)) ) { [self adjustAspectRatio]; } } - (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex; { [super setInputRotation:newInputRotation atIndex:textureIndex]; [self setCenter:self.center]; [self adjustAspectRatio]; } -(void)setDirection:(CGPoint)newValue { _direction = newValue; //CGPoint rotatedPoint = [self rotatedPoint:_direction forRotation:inputRotation]; [self setPoint:_direction forUniform:directionUniform program:filterProgram]; } - (void)setAspectRatio:(CGFloat)newValue; { _aspectRatio = newValue; [self setFloat:_aspectRatio forUniform:aspectRatioUniform program:filterProgram]; } - (void)setRadius:(CGFloat)newValue; { _radius = newValue; [self setFloat:_radius forUniform:radiusUniform program:filterProgram]; } - (void)setScale:(CGFloat)newValue; { _scale = newValue; [self setFloat:_scale forUniform:scaleUniform program:filterProgram]; } - (void)setCenter:(CGPoint)newValue; { _center = newValue; CGPoint rotatedPoint = [self rotatedPoint:_center forRotation:inputRotation]; [self setPoint:rotatedPoint forUniform:centerUniform program:filterProgram]; } @end