iOS 图片高斯模糊处理

2023-02-01  本文已影响0人  Hi小战士

            weakSelf.bgImageView.image= [imageblurImageAtFrame:CGRectMake(0,0, image.size.width, image.size.height)];



- (UIImage*)blurImageAtFrame:(CGRect)frame {



    return [self applyBlurWithRadius:20

                           tintColor:[UIColorcolorWithWhite:0alpha:0.0]

               saturationDeltaFactor:1.4

                           maskImage:nil

                             atFrame:frame];

}

- (UIImage*)applyBlurWithRadius:(CGFloat)blurRadiustintColor:(UIColor*)tintColorsaturationDeltaFactor:(CGFloat)saturationDeltaFactormaskImage:(UIImage*)maskImage {

    // Check pre-conditions.

    if(self.size.width<1||self.size.height<1) {

        NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);

        returnnil;

    }

    if(!self.CGImage) {

        NSLog (@"*** error: image must be backed by a CGImage: %@", self);

        returnnil;

    }

    if(maskImage && !maskImage.CGImage) {

        NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);

        returnnil;

    }

    CGRect  imageRect  = {CGPointZero,self.size};

    UIImage*effectImage =self;

    BOOLhasBlur            = blurRadius >__FLT_EPSILON__;

    BOOLhasSaturationChange =fabs(saturationDeltaFactor -1.) >__FLT_EPSILON__;

    if(hasBlur || hasSaturationChange) {

        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

        CGContextRefeffectInContext =UIGraphicsGetCurrentContext();

        CGContextScaleCTM(effectInContext,1.0, -1.0);

        CGContextTranslateCTM(effectInContext,0, -self.size.height);

        CGContextDrawImage(effectInContext, imageRect,self.CGImage);

        vImage_BuffereffectInBuffer;

        effectInBuffer.data    =CGBitmapContextGetData(effectInContext);

        effectInBuffer.width    =CGBitmapContextGetWidth(effectInContext);

        effectInBuffer.height  =CGBitmapContextGetHeight(effectInContext);

        effectInBuffer.rowBytes=CGBitmapContextGetBytesPerRow(effectInContext);

        UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

        CGContextRefeffectOutContext =UIGraphicsGetCurrentContext();

        vImage_BuffereffectOutBuffer;

        effectOutBuffer.data    =CGBitmapContextGetData(effectOutContext);

        effectOutBuffer.width    =CGBitmapContextGetWidth(effectOutContext);

        effectOutBuffer.height  =CGBitmapContextGetHeight(effectOutContext);

        effectOutBuffer.rowBytes=CGBitmapContextGetBytesPerRow(effectOutContext);

        if(hasBlur) {

            // A description of how to compute the box kernel width from the Gaussian

            // radius (aka standard deviation) appears in the SVG spec:

            // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement

            // 

            // For larger values of 's' (s >= 2.0), an approximation can be used: Three

            // successive box-blurs build a piece-wise quadratic convolution kernel, which

            // approximates the Gaussian kernel to within roughly 3%.

            //

            // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)

            // 

            // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.

            // 

            CGFloatinputRadius = blurRadius * [[UIScreenmainScreen]scale];

            NSUIntegerradius =floor(inputRadius *3.*sqrt(2*M_PI) /4+0.5);

            if(radius %2!=1) {

                radius +=1; // force radius to be odd so that the three box-blur methodology works.

            }

            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer,NULL,0,0, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

            vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer,NULL,0,0, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer,NULL,0,0, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

        }

        BOOLeffectImageBuffersAreSwapped =NO;

        if(hasSaturationChange) {

            CGFloats = saturationDeltaFactor;

            CGFloatfloatingPointSaturationMatrix[] = {

                0.0722+0.9278* s,  0.0722-0.0722* s,  0.0722-0.0722* s,  0,

                0.7152-0.7152* s,  0.7152+0.2848* s,  0.7152-0.7152* s,  0,

                0.2126-0.2126* s,  0.2126-0.2126* s,  0.2126+0.7873* s,  0,

                                  0,                    0,                    0,  1,

            };

            constint32_tdivisor =256;

            NSUIntegermatrixSize =sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);

            int16_tsaturationMatrix[matrixSize];

            for(NSUIntegeri =0; i < matrixSize; ++i) {

                saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);

            }

            if(hasBlur) {

                vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor,NULL,NULL,kvImageNoFlags);

                effectImageBuffersAreSwapped =YES;

            }else{

                vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor,NULL,NULL,kvImageNoFlags);

            }

        }

        if(!effectImageBuffersAreSwapped) {

            effectImage =UIGraphicsGetImageFromCurrentImageContext();

        }

        UIGraphicsEndImageContext();

        if(effectImageBuffersAreSwapped) {

            effectImage =UIGraphicsGetImageFromCurrentImageContext();

        }

        UIGraphicsEndImageContext();

    }

    // Set up output context.

    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

    CGContextRef outputContext = UIGraphicsGetCurrentContext();

    CGContextScaleCTM(outputContext,1.0, -1.0);

    CGContextTranslateCTM(outputContext, 0, -self.size.height);

    // Draw base image.

    CGContextDrawImage(outputContext, imageRect,self.CGImage);

    // Draw effect image.

    if(hasBlur) {

        CGContextSaveGState(outputContext);

        if(maskImage) {

            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);

        }

        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);

        CGContextRestoreGState(outputContext);

    }

    // Add in color tint.

    if(tintColor) {

        CGContextSaveGState(outputContext);

        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);

        CGContextFillRect(outputContext, imageRect);

        CGContextRestoreGState(outputContext);

    }

    // Output image is ready.

    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    returnoutputImage;

}

上一篇 下一篇

猜你喜欢

热点阅读