iOS 模糊效果相关

博客介绍了项目中图片高斯模糊处理的代码,该方法写在UIImage的Category中,用于处理图片效果尚可但耗内存。因项目需对视频进行模糊处理,原方法不再适用,于是找到苹果的UIVisualEffectView进行视频模糊处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中一直有使用到模糊处理, 例如图片的高斯模糊, 一直使用的代码如下:

 

// 内部方法,核心代码,封装了毛玻璃效果 参数:半径,颜色,色彩饱和度

- (UIImage *)imgBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage

{

 

    UIImage *outputImage =nil;

    CGRect imageRect = { CGPointZero, self.size };

    UIImage *effectImage = self;

    

    BOOL hasBlur = blurRadius > __FLT_EPSILON__;

    BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;

    if (hasBlur || hasSaturationChange) {

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

        CGContextRef effectInContext = UIGraphicsGetCurrentContext();

        CGContextScaleCTM(effectInContext, 1.0, -1.0);

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

        CGContextDrawImage(effectInContext, imageRect, self.CGImage);

        

        vImage_Buffer effectInBuffer;

        effectInBuffer.data = CGBitmapContextGetData(effectInContext);

        effectInBuffer.width = CGBitmapContextGetWidth(effectInContext);

        effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);

        effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);

        

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

        CGContextRef effectOutContext = UIGraphicsGetCurrentContext();

        vImage_Buffer effectOutBuffer;

        effectOutBuffer.data = CGBitmapContextGetData(effectOutContext);

        effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext);

        effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);

        effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);

        

        if (hasBlur) {

            CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];

            NSUInteger radius = 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, radius, radius, 0, kvImageEdgeExtend);

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

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

        }

        BOOL effectImageBuffersAreSwapped = NO;

        if (hasSaturationChange) {

            CGFloat s = saturationDeltaFactor;

            CGFloat floatingPointSaturationMatrix[] = {

                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,

            };

            const int32_t divisor = 256;

            NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);

            int16_t saturationMatrix[matrixSize];

            for (NSUInteger i = 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();

    }

    

    // 开启上下文 用于输出图像

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

    CGContextRef outputContext = UIGraphicsGetCurrentContext();

    CGContextScaleCTM(outputContext, 1.0, -1.0);

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

    

    // 开始画底图

    CGContextDrawImage(outputContext, imageRect, self.CGImage);

    

    // 开始画模糊效果

    if (hasBlur) {

        CGContextSaveGState(outputContext);

        if (maskImage) {

            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);

        }

        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);

        CGContextRestoreGState(outputContext);

    }

    

    // 添加颜色渲染

    if (tintColor) {

        CGContextSaveGState(outputContext);

        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);

        CGContextFillRect(outputContext, imageRect);

        CGContextRestoreGState(outputContext);

    }

    

    // 输出成品,并关闭上下文

    outputImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return outputImage;

 

}

该方法是写在UIImage的一个Category中, 一直以来只用于处理图片, 效果还好, 但是比较耗内存

最近项目中要实现对视频模糊处理, 再使用该方法很明显是不可能的

于是找到了下面这种方法, 苹果直接原来有一套模糊处理的view:  UIVisualEffectView

    UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];

    _effectView = [[UIVisualEffectView alloc] initWithEffect:effect];

    _effectView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    [self.chattingView.remoteImageView addSubview:_effectView];

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值