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