2013-08-19 27 views
0

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

验证码:

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

过滤 enter image description here

后过滤 enter image description here

回答

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

希望有所帮助。

2

其实,我只是遇到了这个确切的问题,并找到了与@RizwanSattar描述不同的解决方案。

基于与苹果开发板上的“Rincewind”进行交换,我所做的是首先在图像上应用CIAffineClamp,并将变换值设置为标识。这会以相同的比例创建图像,但具有无限的范围。这会导致模糊效果正确模糊边缘。

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

你可以看到在CI过滤器演示应用程序我已经张贴在GitHub上的代码:

CIFilter demo project on github

这是一个通用的程序,处理不同的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]; 
} 
+0

嘿邓肯!会喜欢这个:)的快速版本 –

相关问题