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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13447474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 02:07:57  来源:igfitidea点击:

CIFilter guassianBlur and boxBlur are shrinking the image - how to avoid the resizing?

objective-cxcodemacoscocoacore-image

提问by foundry

I am taking a snapshot of the contents of an NSView, applying a CIFilter, and placing the result back into the view. If the CIFilteris a form of blur, such as CIBoxBluror CIGuassianBlur, the filtered result is slightly smaller than the original. As I am doing this iteratively the result becomes increasingly small, which I want to avoid.

我正在对 an 的内容进行快照NSView,应用 aCIFilter并将结果放回视图中。如果CIFilter是一种模糊形式,例如CIBoxBlurCIGuassianBlur,则过滤后的结果会比原始结果略小。当我迭代地这样做时,结果变得越来越小,我想避免这种情况。

The issue is alluded to herealbeit in a slightly different context (Quartz Composer). Apple FunHousedemo app applies a Guassian blurwithout the image shrinking, but I haven't yet worked out how this app does it (it seems to be using OpenGLwhich I am not familiar with).

此问题已提到了这里的一个稍微不同的上下文(石英作曲家)虽然。AppleFunHouse演示应用程序应用了一个Guassian blur没有图像缩小的应用程序,但我还没有弄清楚这个应用程序是如何做到的(它似乎正在使用OpenGL我不熟悉的)。

Here is the relevant part of the code (inside an NSViewsubclass)

这是代码的相关部分(在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];

If I try a color-changing filter such as CISepiaTone, which is not shifting pixels around, the shrinking does not occur.

如果我尝试使用CISepiaTone不会移动像素的变色滤镜,例如,则不会发生缩小。

I am wondering if there is a quick fix that doesn't involve diving into openGL?

我想知道是否有不涉及潜入的快速修复openGL

回答by BBC_Z

They're actually not shrinking the image, they're expanding it (I think by 7 pixels around all edges) and the default UIView 'scale To View' makes it looks like it's been shrunk.

他们实际上并没有缩小图像,而是扩大了它(我认为所有边缘周围都扩大了 7 个像素),并且默认的 UIView 'scale To View' 使它看起来像被缩小了。

Crop your CIImage with:

使用以下方法裁剪您的 CIImage:

CIImage *cropped=[output imageByCroppingToRect:CGRectMake(0, 0, view.bounds.size.width*scale, view.bounds.size.height*scale)];

where view is the original bounds of your NSView that you drew into and 'scale' is your [UIScreen mainScreen] scale].

其中 view 是您绘制的 NSView 的原始边界,'scale' 是您的 [UIScreen mainScreen] 比例]。

回答by ccgus

You probably want to clamp your image before using the blur:

您可能想在使用模糊之前夹住图像:

- (CIImage*)imageByClampingToExtent {
    CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"];
    [clamp setValue:[NSAffineTransform transform] forKey:@"inputTransform"];
    [clamp setValue:self forKey:@"inputImage"];
    return [clamp valueForKey:@"outputImage"];
}

Then blur, and then crop to the original extent. You'll get non-transparent edges this way.

然后模糊,然后裁剪到原始范围。这样你会得到不透明的边缘。

回答by IluTov

@BBC_Z's solution is correct.

@BBC_Z 的解决方案是正确的。

Although I find it more elegant to crop not according to the view, but to the image.
And you can cut away the useless blurred edges:

虽然我发现不是根据视图而是根据图像裁剪更优雅。
你可以剪掉无用的模糊边缘:

// 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
}];