Created
December 18, 2012 11:44
-
-
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 …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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