当应用在后台时,CIFilter无法正常工作 [英] CIFilter is not working correctly when app is in background

查看:100
本文介绍了当应用在后台时,CIFilter无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在少量图像上应用'CIGaussianBlur'滤镜。这个过程大部分时间都很好。但是当应用程序移动到后台时,该过程会在图像上产生白色条纹。 (下图中,请注意图像的左下角条纹为白色,与原始图像相比,图像有点尖叫)。

We are applying a 'CIGaussianBlur' filter on few images. The process is working fine most of the time. But when the app moves to the background the process produce whit stripes on the image. (Images below, notice that the left and bottom of the image is striped to white and that the image is shrieked a bit in comparing to the original image).

代码:

 - (UIImage*)imageWithBlurRadius:(CGFloat)radius
{
    UIImage *image = self;
    LOG(@"(1) image size before resize = %@",NSStringFromCGSize(image.size));
    NSData *imageData = UIImageJPEGRepresentation(self, 1.0);
    LOG(@"(2) image data length = %ul",imageData.length);

    //create our blurred image
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];

    //setting up Gaussian Blur (we could use one of many filters offered by Core Image)
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithFloat:radius] forKey:@"inputRadius"];
    CIImage *result = [filter valueForKey:kCIOutputImageKey];
    //CIGaussianBlur has a tendency to shrink the image a little, this ensures it matches up exactly to the bounds of our original image
    CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
    UIImage *finalImage = [UIImage imageWithCGImage:cgImage];

    CGImageRelease(cgImage);
   LOG(@"(3) final image size after resize = %@",NSStringFromCGSize(finalImage.size));
    return finalImage;
}

过滤前

过滤后

推荐答案

实际上,我刚遇到了这个问题,并找到了与@RizwanSattar所描述的解决方案不同的解决方案。

Actually, I just faced this exact problem, and found a solution that's different than what @RizwanSattar describes.

我做什么基于Apple开发板上与Rincewind的交换,首先在图像上应用CIAffineClamp,将变换值设置为identity。这会以相同的比例创建图像,但具有无限的范围。这会导致模糊正确地模糊边缘。

What I do, based on an exchange with "Rincewind" on the Apple developer boards, is to first apply a CIAffineClamp on the image, with the transform value set to identity. This creates an image at the same scale, but with an infinite extent. That causes the blur to blur the edges correctly.

然后在我应用模糊后,我将图像裁剪为原始范围,裁剪掉在边缘。

Then after I apply the blur, I crop the image to it's original extent, cropping away the feathering that takes place on the edges.

你可以看到我在github上发布的CI过滤器演示应用程序中的代码:

You can see the code in a CI Filter demo app I've posted on github:

github上的CIFilter演示项目

这是一个处理所有不同CI过滤器的通用程序,但它有代码来处理高斯模糊过滤器。

It's a general-purpose program that handles all the different CI filters, but it has code to deal with the Gaussian blur filter.

看看方法 showImage 。它具有在应用模糊过滤器之前在源图像上设置范围的特殊情况代码:

Take a look at the method showImage. It has special-case code to set the extent on the source image before applying the blur filter:

if ([currentFilterName isEqualToString: @"CIGaussianBlur"])
{
  // NSLog(@"new image is bigger");
  CIFilter *clampFilter = [self clampFilter];

  CIImage *sourceCIImage = [CIImage imageWithCGImage: imageToEdit.CGImage];
  [clampFilter setValue: sourceCIImage
                 forKey: kCIInputImageKey];


  [clampFilter setValue:[NSValue valueWithBytes: &CGAffineTransformIdentity
                                       objCType:@encode(CGAffineTransform)]
                 forKey:@"inputTransform"];



  sourceCIImage = [clampFilter valueForKey: kCIOutputImageKey];
  [currentFilter setValue: sourceCIImage
                   forKey: kCIInputImageKey];
}

(方法clampFilter懒得加载 CIAffineClamp 过滤器。)

(Where the method "clampFilter" just lazily loads a CIAffineClamp filter.)

然后我应用用户选择的过滤器:

Then I apply the user-selected filter:

outputImage = [currentFilter valueForKey: kCIOutputImageKey];

然后应用选定的过滤器后,我检查生成的图像的范围并将其裁剪回如果它更大的原始范围:

Then after applying the selected filter, I then check the extent of the resulting image and crop it back to the original extent if it's bigger:

CGSize newSize;

newSize = outputImage.extent.size;

if (newSize.width > sourceImageExtent.width || newSize.height > sourceImageExtent.height)
{
  // NSLog(@"new image is bigger");
  CIFilter *cropFilter = [self cropFilter];  //Lazily load a CIAffineClamp filter

  CGRect boundsRect = CGRectMake(0, 0, sourceImageExtent.width, sourceImageExtent.height);

  [cropFilter setValue:outputImage forKey: @"inputImage"];

  CIVector *rectVector = [CIVector vectorWithCGRect: boundsRect];

  [cropFilter setValue: rectVector
                forKey: @"inputRectangle"];
  outputImage = [cropFilter valueForKey: kCIOutputImageKey];
}

这篇关于当应用在后台时,CIFilter无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆