美文网首页图片处理
iOS 手指涂抹--局部模糊图片

iOS 手指涂抹--局部模糊图片

作者: 佐_笾 | 来源:发表于2018-08-15 16:09 被阅读71次

手指涂抹,实现图片局部模糊

最近项目里新增了图片编辑模块,其中一个功能点就是手指涂抹图片,实现图片的局部模糊,网上搜到了关于很多模糊图片的资料,但是关于根据手指路径来模糊图片的基本上没有(马赛克类型的模糊还是存在的),经过一段时间研究之后,实现了功能,本着共享的原则,在这里和大家分享一下,有问题的地方,希望大家指出,谢谢

一、思路

1、实时截取图片部分区域,然后用高斯模糊的方法,再把图片描绘到想要模糊的图层上

2、贝塞尔曲线+CALayer(CAShapeLayer),追加路径的方式,模糊图片

第一种方式,是我一开始着手这个模块的思路,也实现了这个功能,不过很快也就放弃了,经验丰富的只要思考一下,就能想得到,很难做到实时,另外,这种方式,无法做到是非流畅,可以说越是到后期越卡,目前没有想到很好的解决方法,如果哪位大佬有好的方法,请告之

第二种方式,感觉是处理这种功能点最好的方式了,流畅程度非常的完美,这里也是使用Accelerate中的vImage进行高斯模糊

二、遇到的问题

遇到的第一个难点就是上述两种实现方式的选择问题,方向错误给我带了不少麻烦;然后就是自测的时候,你会发现模糊路径的颜色值会发生改变,网上提供了很多的模糊方法,但是都存在不同程度的颜色值改变,后面会给大家提供方法;再者就是撤回操作,撤回操作我的思路是存数组,本人感觉比较简单方便,但是仅仅利用数组里存的image复制给imageView的话,无法实现撤回功能,究其原因在于layer层的问题,有兴趣的可以了解一下

下面分享一下代码:

使用Accelerate中的vImage进行高斯模糊

- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {   

NSData *imageData = UIImageJPEGRepresentation(image, 1); // convert to jpeg   

UIImage* destImage = [UIImage imageWithData:imageData];       

int boxSize = (int)(blur * 100); 

 if (blur > 0.5) {       

boxSize = (int)(blur * 100) + 50;   

}else if (blur <= 0.5) {     

 boxSize = (int)(blur * 100);   

}   

boxSize = boxSize - (boxSize % 2) + 1;       

CGImageRef img = destImage.CGImage;   

vImage_Buffer inBuffer, outBuffer;   

vImage_Error error;    void *pixelBuffer;           //create vImage_Buffer with data from CGImageRef       

CGDataProviderRef inProvider = CGImageGetDataProvider(img);   

CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);     

 inBuffer.width = CGImageGetWidth(img);   

inBuffer.height = CGImageGetHeight(img);   

inBuffer.rowBytes = CGImageGetBytesPerRow(img);       

inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);       //create vImage_Buffer for output   

pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));     

 if(pixelBuffer == NULL)        NSLog(@"No pixelbuffer");       

outBuffer.data = pixelBuffer;   

outBuffer.width = CGImageGetWidth(img);   

outBuffer.height = CGImageGetHeight(img);   

outBuffer.rowBytes = CGImageGetBytesPerRow(img);       // Create a third buffer for intermediate processing   

void *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));   

vImage_Buffer outBuffer2;   

outBuffer2.data = pixelBuffer2;   

outBuffer2.width = CGImageGetWidth(img);   

outBuffer2.height = CGImageGetHeight(img);   

outBuffer2.rowBytes = CGImageGetBytesPerRow(img);        //perform convolution   

error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);   

if (error) {        NSLog(@"error from convolution %ld", error);    }   

error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);   

if (error) {        NSLog(@"error from convolution %ld", error);    } 

 error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);   

if (error) {        NSLog(@"error from convolution %ld", error);    }       

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();   

CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,                                             outBuffer.width,                                             outBuffer.height,                                             8,                                             outBuffer.rowBytes,                                             colorSpace,                                             (CGBitmapInfo)kCGImageAlphaNoneSkipLast);   

CGImageRef imageRef = CGBitmapContextCreateImage (ctx);   

UIImage *returnImage = [UIImage imageWithCGImage:imageRef];       //clean up   

CGContextRelease(ctx);   

CGColorSpaceRelease(colorSpace);       

free(pixelBuffer); 

free(pixelBuffer2);   

CFRelease(inBitmapData);       

CGImageRelease(imageRef);       

return returnImage;

}

添加CAShapeLayer

- (void)addCAShapeLayer {     

CALayer *imageLayer = [CALayer layer];     

imageLayer.frame = self.imageView.bounds;     

[self.imageView.layer addSublayer:imageLayer];          

_shapeLayer = [CAShapeLayer layer];    

_shapeLayer.frame = self.imageView.bounds;     

_shapeLayer.lineCap = kCALineCapRound;     

_shapeLayer.lineJoin = kCALineJoinRound;     

_fuzzyWith = (34 * _fuzzySizeValue) + 8;  

 _shapeLayer.lineWidth = _fuzzyWith;     

_shapeLayer.strokeColor = [[UIColor whiteColor] CGColor];    

_shapeLayer.fillColor = nil;     

[self.imageView.layer addSublayer:_shapeLayer];       

imageLayer.mask = _shapeLayer;          

self.path = CGPathCreateMutable();     

UIImage *img1 = [self blurryImage:_image withBlurLevel:_fuzzyDegreeValue];     

imageLayer.contents = (id)img1.CGImage;

}

由于项目需求,demo里提供了改变画笔(轨迹路径的大小)大小,以及模糊程度的slider,为了方便大家,封装的demo有接口,直接传值即可;总结一下,高斯模糊有很多种,Accelerate 的模糊是最靠谱的,速度和效果都非常完美,只是会占用更高的cpu。

demo地址:GitHub - SXDgit/ZBFuzzyImageDemo: 图片处理,手指涂抹图片,使图片局部模糊

相关文章

  • iOS 手指涂抹--局部模糊图片

    手指涂抹,实现图片局部模糊 最近项目里新增了图片编辑模块,其中一个功能点就是手指涂抹图片,实现图片的局部模糊,网上...

  • mac osx 涂抹马赛克实现

    实现原理 参考 iOS手指涂抹位置变马赛克的实现 实现 mac osx 版本 图片马赛克实现 借助CoreImag...

  • 图片马赛克处理

    图片涂抹马赛克逻辑步骤: 打开一张图片为前景图片 以前景图片生成一张虚化后的图片为背景图片 手指在屏幕涂抹,根据手...

  • 批量图片局部高斯模糊(图片水印处理)

    前言: 本人菜鸟,不对的地方请指正,勿喷,感激不尽~~ 背景: 公司让我扒了一些文章,要保持文章结构,图片正确穿插...

  • iOS 图片模糊效果

    1.使用CoreImage中的模糊滤镜原始效果图如下:这里写图片描述 CoreImage的实现: UIImage ...

  • ios 图片高斯模糊

  • iOS图片模糊处理

    下面是一个图片模糊处理的扩展方法,给予有需要用到的伙伴建立一个imgView 的分类方便直接调用 .h .m

  • iOS - 图片模糊效果

    vImage 方式添加通用模糊效果

  • iOS 图片模糊效果

    1. CoreImage中的模糊滤镜 高斯模糊效果图 高斯模糊前后对比.png 核心代码 2. UIImage+I...

  • 图片高斯模糊效果

    iOS开发的时候有的时候需要将图片设置模糊,或者通过点击下拉方法,去除模糊。关于图片实现高斯模糊效果有三种方式,C...

网友评论

    本文标题:iOS 手指涂抹--局部模糊图片

    本文链接:https://www.haomeiwen.com/subject/fpywbftx.html