iOS , Image Unit MacOS X, , , Image Unit iOS. , "" , Image Unit; , . , ; iOS , MacOS X, Core Image. .
, Core Image iOS , Image Unit. , .plist -.
iOS - Cocoa Touch, CIFilter; ( ), , Core Image. OpenGL , CIKernel, .cycernel, .
Core Image iOS , , :
CIFilter* PrewittKernel = [CIFilter filterWithName:@"PrewittKernel"];
CIImage *result = [CIFilter filterWithName:@"PrewittKernel" keysAndValues:kCIInputImageKey, self.inputImage, nil].outputImage;
, OpenGL Prewitt ; -, Cocoa Touch Class ( CIFilter), CIKernel ( OpenGL ES 3.0):
:
#import <CoreImage/CoreImage.h>
@interface PrewittKernel : CIFilter
{
CIImage *inputImage;
}
@property (retain, nonatomic) CIImage *inputImage;
@end
:
#import <CoreImage/CoreImage.h>
@interface PrewittKernel : CIFilter
{
CIImage *inputImage;
}
@property (retain, nonatomic) CIImage *inputImage;
@end
@implementation PrewittKernel
@synthesize inputImage;
- (CIKernel *)prewittKernel
{
static CIKernel *kernelPrewitt = nil;
NSBundle *bundle = [NSBundle bundleForClass:NSClassFromString(@"PrewittKernel")];
NSStringEncoding encoding = NSUTF8StringEncoding;
NSError *error = nil;
NSString *code = [NSString stringWithContentsOfFile:[bundle pathForResource:@"PrewittKernel" ofType:@"cikernel"] encoding:encoding error:&error];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
kernelPrewitt = [CIKernel kernelWithString:code];
});
return kernelPrewitt;
}
- (CIImage *)outputImage
{
CIImage *result = self.inputImage;
return [[self prewittKernel] applyWithExtent:result.extent roiCallback:^CGRect(int index, CGRect rect) {
return CGRectMake(0, 0, CGRectGetWidth(result.extent), CGRectGetHeight(result.extent));
} arguments:@[result]];
}
@end
CIKernel (OpenGL ES 3.0):
/* PrewittKernel.cikernel */
kernel vec4 prewittKernel(sampler image)
{
vec2 xy = destCoord();
vec4 bottomLeftIntensity = sample(image, samplerTransform(image, xy + vec2(-1, -1)));
vec4 topRightIntensity = sample(image, samplerTransform(image, xy + vec2(+1, +1)));
vec4 topLeftIntensity = sample(image, samplerTransform(image, xy + vec2(+1, -1)));
vec4 bottomRightIntensity = sample(image, samplerTransform(image, xy + vec2(-1, +1)));
vec4 leftIntensity = sample(image, samplerTransform(image, xy + vec2(-1, 0)));
vec4 rightIntensity = sample(image, samplerTransform(image, xy + vec2(+1, 0)));
vec4 bottomIntensity = sample(image, samplerTransform(image, xy + vec2(0, -1)));
vec4 topIntensity = sample(image, samplerTransform(image, xy + vec2(0, +1)));
vec4 h = vec4(-topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity);
vec4 v = vec4(-bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity);
float h_max = max(h.r, max(h.g, h.b));
float v_max = max(v.r, max(v.g, v.b));
float mag = length(vec2(h_max, v_max)) * 1.0;
return vec4(vec3(mag), 1.0);
}
, (, , ) Core Image - Core Image (OpenGL); , , , :
:
#import <CoreImage/CoreImage.h>
@interface GaussianKernel : CIFilter
{
CIImage *inputImage;
NSNumber *inputRadius;
}
@property (retain, nonatomic) CIImage *inputImage;
@property (retain, nonatomic) NSNumber *inputRadius;
@end
:
#import "GaussianKernel.h"
@implementation GaussianKernel
@synthesize inputImage;
@synthesize inputRadius;
+ (NSDictionary *)customAttributes
{
return @{
@"inputRadius" :
@{
kCIAttributeMin : @3.0,
kCIAttributeMax : @15.0,
kCIAttributeDefault : @7.5,
kCIAttributeType : kCIAttributeTypeScalar
}
};
}
- (void)setDefaults
{
self.inputRadius = @7.5;
}
- (CIImage *)outputImage
{
CIImage *result = self.inputImage;
CGRect rect = [[GlobalCIImage sharedSingleton].ciImage extent];
rect.origin = CGPointZero;
CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width, rect.size.height);
CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width W:rect.size.height];
result = [[CIFilter filterWithName:@"CIGaussianBlur" keysAndValues:kCIInputImageKey, result, @"inputRadius", [NSNumber numberWithFloat:inputRadius.floatValue], nil].outputImage imageByCroppingToRect:cropRectLeft];
result = [CIFilter filterWithName:@"CICrop" keysAndValues:@"inputImage", result, @"inputRectangle", cropRect, nil].outputImage;
result = [CIFilter filterWithName:@"CIDifferenceBlendMode" keysAndValues:kCIInputImageKey, result, kCIInputBackgroundImageKey, result, nil].outputImage;
return result;
}
@end