Skip to content

Instantly share code, notes, and snippets.

@julienp
Created December 18, 2012 11:44
Show Gist options
  • Save julienp/4327330 to your computer and use it in GitHub Desktop.
Save julienp/4327330 to your computer and use it in GitHub Desktop.
Tiltshift filter for CoreImage Top, center and bottom are floats in [0, 1] and control the gradients used to blend the blurred and original image together. The gradients go from (imageHeight * bottom) to (imageHeight * center) and from (imageHeight * top) to (imageHeight * center). This should probably be changed to take CIVectors in unit space …
#import <CoreImage/CoreImage.h>
@interface JPTiltShift : CIFilter
@property (retain, nonatomic) CIImage *inputImage;
@property (assign, nonatomic) CGFloat inputRadius;
@property (assign, nonatomic) CGFloat inputTop;
@property (assign, nonatomic) CGFloat inputCenter;
@property (assign, nonatomic) CGFloat inputBottom;
@end
#import "JPTiltShift.h"
@implementation JPTiltShift
- (void)setDefaults
{
[self setValue:@(10) forKey:@"inputRadius"];
[self setValue:@(0.5) forKey:@"inputCenter"];
[self setValue:@(0.25) forKey:@"inputBottom"];
[self setValue:@(0.75) forKey:@"inputTop"];
}
- (CIImage *)outputImage
{
CGRect cropRect = self.inputImage.extent;
CGFloat height = cropRect.size.height;
CIFilter *blur = [CIFilter filterWithName:@"CIGaussianBlur"
keysAndValues:@"inputImage", self.inputImage,
@"inputRadius", @(self.inputRadius), nil];
blur = [CIFilter filterWithName:@"CICrop"
keysAndValues:@"inputImage", blur.outputImage,
@"inputRectangle", [CIVector vectorWithCGRect:cropRect], nil];
CIFilter *topGradient = [CIFilter filterWithName:@"CILinearGradient"
keysAndValues:@"inputPoint0", [CIVector vectorWithX:0 Y:(self.inputTop * height)],
@"inputColor0", [CIColor colorWithRed:0 green:1 blue:0 alpha:1],
@"inputPoint1", [CIVector vectorWithX:0 Y:(self.inputCenter * height)],
@"inputColor1", [CIColor colorWithRed:0 green:1 blue:0 alpha:0], nil];
CIFilter *bottomGradient = [CIFilter filterWithName:@"CILinearGradient"
keysAndValues:@"inputPoint0", [CIVector vectorWithX:0 Y:(self.inputBottom * height)],
@"inputColor0", [CIColor colorWithRed:0 green:1 blue:0 alpha:1],
@"inputPoint1", [CIVector vectorWithX:0 Y:(self.inputCenter * height)],
@"inputColor1", [CIColor colorWithRed:0 green:1 blue:0 alpha:0], nil];
topGradient = [CIFilter filterWithName:@"CICrop"
keysAndValues:@"inputImage", topGradient.outputImage,
@"inputRectangle", [CIVector vectorWithCGRect:cropRect], nil];
bottomGradient = [CIFilter filterWithName:@"CICrop"
keysAndValues:@"inputImage", bottomGradient.outputImage,
@"inputRectangle", [CIVector vectorWithCGRect:cropRect], nil];
CIFilter *gradients = [CIFilter filterWithName:@"CIAdditionCompositing"
keysAndValues:@"inputImage", topGradient.outputImage,
@"inputBackgroundImage", bottomGradient.outputImage, nil];
CIFilter *tiltShift = [CIFilter filterWithName:@"CIBlendWithMask"
keysAndValues:@"inputImage", blur.outputImage,
@"inputBackgroundImage", self.inputImage,
@"inputMaskImage", gradients.outputImage, nil];
return tiltShift.outputImage;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment