我正在拍摄NSView
内容的快照,应用CIFilter
,并将结果放回视图中。如果CIFilter
是一种模糊形式,例如CIBoxBlur
或CIGuassianBlur
,则过滤结果略小于原始结果。正如我在迭代地做这个,结果变得越来越小,我想避免。
here提到了这个问题,尽管情况略有不同(Quartz Composer)。 Apple FunHouse
演示应用应用Guassian blur
而不会缩小图像,但我还没有弄清楚这个应用是如何做到的(它似乎是使用我不熟悉的OpenGL
)。
以下是代码的相关部分(在NSView
子类中)
NSImage* background = [[NSImage alloc] initWithData:[self dataWithPDFInsideRect:[self bounds]]];
CIContext* context = [[NSGraphicsContext currentContext] CIContext];
CIImage* ciImage = [background ciImage];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
keysAndValues: kCIInputImageKey, ciImage,
@"inputRadius", [NSNumber numberWithFloat:10.0], nil];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result
fromRect:[result extent]];
NSImage* newBackground = [[NSImage alloc] initWithCGImage:cgImage size:background.size];
如果我尝试使用CISepiaTone
等变色滤镜(不会移动像素),则不会发生缩小。
我想知道是否有一个快速修复不涉及潜入openGL
?
答案 0 :(得分:16)
它们实际上并没有缩小图像,它们正在扩展它(我认为所有边缘都有7个像素)和默认的UIView'缩放到视图'使它看起来像是缩小了。
使用以下方法裁剪您的CIImage:
CIImage *cropped=[output imageByCroppingToRect:CGRectMake(0, 0, view.bounds.size.width*scale, view.bounds.size.height*scale)];
其中view是你所引入的NSView的原始边界,'scale'是你的[UIScreen mainScreen]比例]。
答案 1 :(得分:14)
您可能希望在使用模糊之前夹住图像:
- (CIImage*)imageByClampingToExtent {
CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"];
[clamp setValue:[NSAffineTransform transform] forKey:@"inputTransform"];
[clamp setValue:self forKey:@"inputImage"];
return [clamp valueForKey:@"outputImage"];
}
然后模糊,然后裁剪到原始范围。你会以这种方式得到不透明的边缘。
答案 2 :(得分:4)
@ BBC_Z的解决方案是正确的。
虽然我发现不是根据视图裁剪更优雅,而是根据图像裁剪 你可以切掉无用的模糊边缘:
// Crop transparent edges from blur
resultImage = [resultImage imageByCroppingToRect:(CGRect){
.origin.x = blurRadius,
.origin.y = blurRadius,
.size.width = originalCIImage.extent.size.width - blurRadius*2,
.size.height = originalCIImage.extent.size.height - blurRadius*2
}];