【作者前言】:13年入圈,分享些本人工作中遇到的點點滴滴那些事兒秕噪,17年剛開始寫博客牍蜂,高手勿噴漾根!以分享交流為主,歡迎各路豪杰點評改進鲫竞!
1.應(yīng)用場景:
Paste_Image.png
2.實現(xiàn)目標(biāo):
通過對圖片的處理辐怕,實現(xiàn)毛玻璃效果,這里因為有些時候模糊程度是因具體需求變化的从绘,所以把方法寫活了菜拓,方便大家的調(diào)用遗菠。
3.代碼說明:
方式一纹蝴,推薦使用盐杂,效果比較好!Swift版本已更新批什!
#pragma mark -
#pragma mark - yp_blurryImage: withBlurLevel: 傳入圖片返回設(shè)置毛玻璃效果后的圖片
/** Attention points:
① 需要引入#import <Accelerate/Accelerate.h>
② 傳入變量 blur 代表毛玻璃設(shè)置的程度农曲,值越大越模糊 范圍須在0-1中間,默認為0.5
*/
- (UIImage *)yp_blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {
if (blur < 0.f || blur > 1.f) {
blur = 0.5f;
}
int boxSize = (int)(blur * 40);
boxSize = boxSize - (boxSize % 2) + 1;
CGImageRef img = image.CGImage;
vImage_Buffer inBuffer, outBuffer;
vImage_Error error;
void *pixelBuffer;
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);
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);
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,
kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
//clean up
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
free(pixelBuffer);
CFRelease(inBitmapData);
CGColorSpaceRelease(colorSpace);
CGImageRelease(imageRef);
return returnImage;
}
//使用時直接調(diào)用即可
UIImage * image = [UIImage imageNamed:@"wukong"];
self.blurryImageView.image = [self yp_blurryImage:image withBlurLevel:0.1];
方式二,代碼簡潔驻债,效果欠佳
//創(chuàng)建毛玻璃
UIBlurEffect * blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView * effe = [[UIVisualEffectView alloc] initWithEffect:blur];
//毛玻璃大小與所需要添加毛玻璃效果的大小一致
effe.frame = CGRectMake(0,0,self.blurryImageView.frame.size.width - 100,self.blurryImageView.frame.size.width - 100);
effe.layer.masksToBounds = YES;
effe.layer.cornerRadius = 5;
//透明度為1時乳规,毛玻璃程度為最明顯
effe.alpha = 0.5;
//把要添加的視圖加到毛玻璃上
[self.blurryImageView addSubview:effe];
兩種方法均設(shè)置為0.5時的效果如下圖
Paste_Image.png
??有的朋友需要方法一的swift版本,抽空翻譯了一版却汉,支持最新Swift4語法
注意
:需要導(dǎo)入 Accelerate驯妄,即: #import Accelerate
func yp_burryImage(image:UIImage, blur:CGFloat) -> UIImage {
let blur = (blur < 0.0 || blur > 1.0) ? 0.5 : blur;
var boxSize = Int(blur * 40)
boxSize = boxSize - (boxSize % 2) + 1
let cgImg = image.cgImage
var inBuffer = vImage_Buffer()
var outBuffer = vImage_Buffer()
var pixelBuffer: UnsafeMutableRawPointer
let inProvider = cgImg?.dataProvider
let inBitmapData = inProvider?.data
inBuffer.width = vImagePixelCount((cgImg?.width)!)
inBuffer.height = vImagePixelCount((cgImg?.height)!)
inBuffer.rowBytes = (cgImg?.bytesPerRow)!
inBuffer.data = UnsafeMutableRawPointer(mutating: CFDataGetBytePtr(inBitmapData))
//手動申請內(nèi)存---
pixelBuffer = malloc((cgImg?.bytesPerRow)! * (cgImg?.height)!)
outBuffer.data = pixelBuffer
outBuffer.width = vImagePixelCount((cgImg?.width)!)
outBuffer.height = vImagePixelCount((cgImg?.height)!)
outBuffer.rowBytes = (cgImg?.bytesPerRow)!
var error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, vImagePixelCount(0), vImagePixelCount(0), UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend))
if error != kvImageNoError {
error = vImageBoxConvolve_ARGB8888(&inBuffer,&outBuffer, nil, vImagePixelCount(0), vImagePixelCount(0),UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend))
if (kvImageNoError != error)
{
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, nil, vImagePixelCount(0), vImagePixelCount(0), UInt32(boxSize), UInt32(boxSize), nil, vImage_Flags(kvImageEdgeExtend))
}
}
let colorSpace = CGColorSpaceCreateDeviceRGB()
let ctx = CGContext(data: outBuffer.data, width: Int(outBuffer.width), height: Int(outBuffer.height), bitsPerComponent: 8, bytesPerRow: outBuffer.rowBytes, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
let imageRef = ctx!.makeImage()
let returnImage = UIImage.init(cgImage: imageRef!)
//clean up --- 清理內(nèi)存
free(pixelBuffer)
return returnImage
}