CIFilter guassianBlur和boxBlur正在缩小图像 - 如何避免调整大小?

时间:2012-11-19 03:57:43

标签: objective-c xcode macos cocoa core-image

我正在拍摄NSView内容的快照,应用CIFilter,并将结果放回视图中。如果CIFilter是一种模糊形式,例如CIBoxBlurCIGuassianBlur,则过滤结果略小于原始结果。正如我在迭代地做这个,结果变得越来越小,我想避免。

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

3 个答案:

答案 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
}];