2013-08-19 60 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

嘿鄧肯!會喜歡這個:)的快速版本 –

相關問題