欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS7 毛玻璃特效代码

程序员文章站 2021-12-08 11:55:28
原图: 效果图:  实现: 首先需要导入accelerate.framework。 然后把两个文件加入到自己的项目中即可。 uiimage+...

原图:

iOS7 毛玻璃特效代码

效果图:

iOS7 毛玻璃特效代码

 实现:
首先需要导入accelerate.framework。
然后把两个文件加入到自己的项目中即可。
uiimage+imageeffects.h

复制代码 代码如下:

#import
@interfaceuiimage(imageeffects)
-(uiimage*)applylighteffect;
-(uiimage*)applyextralighteffect;
-(uiimage*)applydarkeffect;
-(uiimage*)applytinteffectwithcolor:(uicolor*)tintcolor;
-(uiimage*)applyblurwithradius:(cgfloat)blurradius tintcolor:(uicolor*)tintcolor saturationdeltafactor:(cgfloat)saturationdeltafactor maskimage:(uiimage*)maskimage;
@end

uiimage+imageeffects.m

复制代码 代码如下:

#import "uiimage+imageeffects.h"
#import
#import
@implementationuiimage(imageeffects)
-(uiimage*)applylighteffect
{
uicolor*tintcolor =[uicolor colorwithwhite:1.0 alpha:0.3];
return[self applyblurwithradius:30 tintcolor:tintcolor saturationdeltafactor:1.8 maskimage:nil];
}
-(uiimage*)applyextralighteffect
{
uicolor*tintcolor =[uicolor colorwithwhite:0.97 alpha:0.82];
return[self applyblurwithradius:20 tintcolor:tintcolor saturationdeltafactor:1.8 maskimage:nil];
}
-(uiimage*)applydarkeffect
{
uicolor*tintcolor =[uicolor colorwithwhite:0.11 alpha:0.73];
return[self applyblurwithradius:20 tintcolor:tintcolor saturationdeltafactor:1.8 maskimage:nil];
}
-(uiimage*)applytinteffectwithcolor:(uicolor*)tintcolor
{
constcgfloateffectcoloralpha=0.6;
uicolor*effectcolor = tintcolor;
int componentcount =cgcolorgetnumberofcomponents(tintcolor.cgcolor);
if(componentcount ==2){
cgfloat b;
if([tintcolor getwhite:&b alpha:null]){
effectcolor =[uicolor colorwithwhite:b alpha:effectcoloralpha];
}
}
else{
cgfloat r, g, b;
if([tintcolor getred:&r green:&g blue:&b alpha:null]){
effectcolor =[uicolor colorwithred:r green:g blue:b alpha:effectcoloralpha];
}
}
return[self applyblurwithradius:10 tintcolor:effectcolor saturationdeltafactor:-1.0 maskimage:nil];
}
-(uiimage*)applyblurwithradius:(cgfloat)blurradius tintcolor:(uicolor*)tintcolor saturationdeltafactor:(cgfloat)saturationdeltafactor maskimage:(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: );
returnnil;
}
if(!self.cgimage){
nslog(@"*** error: image must be backed by a cgimage: );
returnnil;
}
if(maskimage &&!maskimage.cgimage){
nslog(@"*** error: maskimage must be backed by a cgimage: %@", maskimage);
returnnil;
}
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){
// 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.
//
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,
};
constint32_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();
}
// 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();
return outputimage;
}
@end

调用:
 

复制代码 代码如下:

uiimageview*me =[[uiimageview alloc] initwithframe:cgrectmake(10,480,614,381)];
[me setimage:[[uiimage imagenamed:@"me.png"] applyblurwithradius:5 tintcolor:[uicolor colorwithwhite:1 alpha:0.2] saturationdeltafactor:1.8 maskimage:nil]];
[self.view addsubview:me];

ok!so easy!