Correct crop of CIGaussianBlur

后端 未结 9 1570
北海茫月
北海茫月 2020-11-29 22:09

As I noticed when CIGaussianBlur is applied to image, image\'s corners gets blurred so that it looks like being smaller than original. So I figured out that I need to crop i

相关标签:
9条回答
  • 2020-11-29 22:27

    Try this, let the input's extent be -createCGImage:fromRect:'s parameter:

    -(UIImage *)gaussianBlurImageWithRadius:(CGFloat)radius {
        CIContext *context = [CIContext contextWithOptions:nil];
        CIImage *input = [CIImage imageWithCGImage:self.CGImage];
        CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
        [filter setValue:input forKey:kCIInputImageKey];
        [filter setValue:@(radius) forKey:kCIInputRadiusKey];
        CIImage *output = [filter valueForKey:kCIOutputImageKey];
        CGImageRef imgRef = [context createCGImage:output
                                          fromRect:input.extent];
        UIImage *outImage = [UIImage imageWithCGImage:imgRef
                                                scale:UIScreen.mainScreen.scale
                                          orientation:UIImageOrientationUp];
        CGImageRelease(imgRef);
        return outImage;
    }
    
    0 讨论(0)
  • 2020-11-29 22:31

    Take the following code as an example...

    CIContext *context = [CIContext contextWithOptions:nil];
    
    CIImage *inputImage = [[CIImage alloc] initWithImage:image];
    
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    
    [filter setValue:inputImage forKey:kCIInputImageKey];
    
    [filter setValue:[NSNumber numberWithFloat:5.0f] forKey:@"inputRadius"];
    
    CIImage *result = [filter valueForKey:kCIOutputImageKey];
    
    CGImageRef cgImage = [context createCGImage:result fromRect:[result extent]];
    
    

    This results in the images you provided above. But if I instead use the original images rect to create the CGImage off of the context the resulting image is the desired size.

    CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
    0 讨论(0)
  • 2020-11-29 22:33

    See below two implementations for Xamarin (C#).

    1) Works for iOS 6

    public static UIImage Blur(UIImage image)
    {   
        using(var blur = new CIGaussianBlur())
        {
            blur.Image = new CIImage(image);
            blur.Radius = 6.5f;
    
            using(CIImage output = blur.OutputImage)
            using(CIContext context = CIContext.FromOptions(null))
            using(CGImage cgimage = context.CreateCGImage (output, new RectangleF(0, 0, image.Size.Width, image.Size.Height)))
            {
                return UIImage.FromImage(cgimage);
            }
        }
    }
    

    2) Implementation for iOS 7

    Using the way shown above isn't working properly on iOS 7 anymore (at least at the moment with Xamarin 7.0.1). So I decided to add cropping another way (measures may depend on the blur radius).

    private static UIImage BlurImage(UIImage image)
    {   
        using(var blur = new CIGaussianBlur())
        {
            blur.Image = new CIImage(image);
            blur.Radius = 6.5f;
    
            using(CIImage output = blur.OutputImage)
            using(CIContext context = CIContext.FromOptions(null))
            using(CGImage cgimage = context.CreateCGImage (output, new RectangleF(0, 0, image.Size.Width, image.Size.Height)))
            {
                return UIImage.FromImage(Crop(CIImage.FromCGImage(cgimage), image.Size.Width, image.Size.Height));
            }
        }
    }
    
    private static CIImage Crop(CIImage image, float width, float height)
    {
        var crop = new CICrop
        { 
            Image = image,
            Rectangle = new CIVector(10, 10, width - 20, height - 20) 
        };
    
        return crop.OutputImage;   
    }
    
    0 讨论(0)
提交回复
热议问题