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

Leave a Reply