我们正在少量图像上应用'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无法正常工作
发布评论