0

我们正在对少数图像应用“CIGaussianBlur”过滤器。该过程大部分时间都运行良好。但是当应用程序移动到后台时,该过程会在图像上产生白色条纹。(下面的图像,请注意图像的左侧和底部条纹为白色,并且与原始图像相比,图像有点尖叫)。

编码:

 - (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;
}

过滤前 在此处输入图像描述

过滤后 在此处输入图像描述

4

2 回答 2

2

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

我所做的,基于在 Apple 开发人员板上与“Rincewind”的交流,首先在图像上应用 CIAffineClamp,并将变换值设置为身份。这将创建相同比例的图像,但范围无限。这会导致模糊正确地模糊边缘。

然后在我应用模糊之后,我将图像裁剪到原始范围,裁剪掉边缘发生的羽化。

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

github上的CIFilter演示项目

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

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

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过滤器。)

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

outputImage = [currentFilter valueForKey: kCIOutputImageKey];

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

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];
}
于 2014-03-29T13:07:32.050 回答
0

您在模糊图像中看到那些“白条”的原因是生成的 CIImage原始图像大,因为它具有模糊的模糊边缘。当您将生成的图像硬裁剪为与原始图像相同的大小时,它并没有考虑到模糊边缘。

后:

CIImage *result = [filter valueForKey:kCIOutputImageKey];

看看result.extent哪个是 CGRect,它显示了相对于原始图像的新边界框。(即对于正半径,result.extent.origin.y将是负数)

这是一些代码(您应该真正测试一下):

CIImage *result = blurFilter.outputImage;

// Blur filter will create a larger image to cover the "fuzz", but
// we should cut it out since goes to transparent and it looks like a
// vignette
CGFloat imageSizeDifference = -result.extent.origin.x;
// NOTE: on iOS7 it seems to generate an image that will end up still vignetting, so
// as a hack just multiply the vertical inset by 2x
CGRect imageInset = CGRectInset(result.extent, imageSizeDifference, imageSizeDifference*2);

CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:result fromRect:imageInset];

希望有帮助。

于 2013-12-10T00:27:45.093 回答