UIScrollview - 模糊效果 iOS
Posted
技术标签:
【中文标题】UIScrollview - 模糊效果 iOS【英文标题】:UIScrollview - Blurry effects iOS 【发布时间】:2012-09-20 02:51:29 【问题描述】:我有分页 UIScrollview。 UIScrollview 是用户选择的选项。我应该模糊那些不在滚动视图框架内的页面。对此有何建议?这是实现的 UIScrollview 的screenshot。低 alpha 分量的黑框将被其他页面上的模糊效果替换。
【问题讨论】:
你试过什么?显然,通过使用 CALayer 标记来标记这个问题,您已经完成了一些类似的实现。 dimzzy.com/blog/2010/11/blur-effect-for-uiview 我看到了这个链接。然而,要在那些不在框架内的***上添加模糊效果,我需要在滚动视图顶部和框架外添加模糊效果。这将不允许我滚动 UIScrollview,因为它位于模糊的 UIView 下方。 【参考方案1】:我通过UIImage
上的一个类别实现了这一目标...
.h 文件:
#import <Foundation/Foundation.h>
@interface UIImage (StackBlur)
- (UIImage*) stackBlur:(NSUInteger)radius;
- (UIImage *) normalize ;
@end
.m 文件:
#import "UIImage+StackBlur.h"
@implementation UIImage (StackBlur)
// Stackblur algorithm
// from
// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php
// by Mario Klingemann
- (UIImage*) stackBlur:(NSUInteger)inradius
int radius=inradius; // Transform unsigned into signed for further operations
if (radius<1)
return self;
// Suggestion xidew to prevent crash if size is null
if (CGSizeEqualToSize(self.size, CGSizeZero))
return self;
// return [other applyBlendFilter:filterOverlay other:self context:nil];
// First get the image into your data buffer
CGImageRef inImage = self.CGImage;
int nbPerCompt=CGImageGetBitsPerPixel(inImage);
if(nbPerCompt!=32)
UIImage *tmpImage=[self normalize];
inImage=tmpImage.CGImage;
CFDataRef m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
UInt8 * m_PixelBuf=malloc(CFDataGetLength(m_DataRef));
CFDataGetBytes(m_DataRef,
CFRangeMake(0,CFDataGetLength(m_DataRef)) ,
m_PixelBuf);
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf,
CGImageGetWidth(inImage),
CGImageGetHeight(inImage),
CGImageGetBitsPerComponent(inImage),
CGImageGetBytesPerRow(inImage),
CGImageGetColorSpace(inImage),
CGImageGetBitmapInfo(inImage)
);
int w=CGImageGetWidth(inImage);
int h=CGImageGetHeight(inImage);
int wm=w-1;
int hm=h-1;
int wh=w*h;
int div=radius+radius+1;
int *r=malloc(wh*sizeof(int));
int *g=malloc(wh*sizeof(int));
int *b=malloc(wh*sizeof(int));
memset(r,0,wh*sizeof(int));
memset(g,0,wh*sizeof(int));
memset(b,0,wh*sizeof(int));
int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
int *vmin = malloc(sizeof(int)*MAX(w,h));
memset(vmin,0,sizeof(int)*MAX(w,h));
int divsum=(div+1)>>1;
divsum*=divsum;
int *dv=malloc(sizeof(int)*(256*divsum));
for (i=0;i<256*divsum;i++)
dv[i]=(i/divsum);
yw=yi=0;
int *stack=malloc(sizeof(int)*(div*3));
int stackpointer;
int stackstart;
int *sir;
int rbs;
int r1=radius+1;
int routsum,goutsum,boutsum;
int rinsum,ginsum,binsum;
memset(stack,0,sizeof(int)*div*3);
for (y=0;y<h;y++)
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
for(int i=-radius;i<=radius;i++)
sir=&stack[(i+radius)*3];
/* p=m_PixelBuf[yi+MIN(wm,MAX(i,0))];
sir[0]=(p & 0xff0000)>>16;
sir[1]=(p & 0x00ff00)>>8;
sir[2]=(p & 0x0000ff);
*/
int offset=(yi+MIN(wm,MAX(i,0)))*4;
sir[0]=m_PixelBuf[offset];
sir[1]=m_PixelBuf[offset+1];
sir[2]=m_PixelBuf[offset+2];
rbs=r1-abs(i);
rsum+=sir[0]*rbs;
gsum+=sir[1]*rbs;
bsum+=sir[2]*rbs;
if (i>0)
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
else
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
stackpointer=radius;
for (x=0;x<w;x++)
r[yi]=dv[rsum];
g[yi]=dv[gsum];
b[yi]=dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=&stack[(stackstart%div)*3];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(y==0)
vmin[x]=MIN(x+radius+1,wm);
/* p=m_PixelBuf[yw+vmin[x]];
sir[0]=(p & 0xff0000)>>16;
sir[1]=(p & 0x00ff00)>>8;
sir[2]=(p & 0x0000ff);
*/
int offset=(yw+vmin[x])*4;
sir[0]=m_PixelBuf[offset];
sir[1]=m_PixelBuf[offset+1];
sir[2]=m_PixelBuf[offset+2];
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=&stack[((stackpointer)%div)*3];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi++;
yw+=w;
for (x=0;x<w;x++)
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++)
yi=MAX(0,yp)+x;
sir=&stack[(i+radius)*3];
sir[0]=r[yi];
sir[1]=g[yi];
sir[2]=b[yi];
rbs=r1-abs(i);
rsum+=r[yi]*rbs;
gsum+=g[yi]*rbs;
bsum+=b[yi]*rbs;
if (i>0)
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
else
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
if(i<hm)
yp+=w;
yi=x;
stackpointer=radius;
for (y=0;y<h;y++)
// m_PixelBuf[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
int offset=yi*4;
m_PixelBuf[offset]=dv[rsum];
m_PixelBuf[offset+1]=dv[gsum];
m_PixelBuf[offset+2]=dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=&stack[(stackstart%div)*3];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(x==0)
vmin[y]=MIN(y+r1,hm)*w;
p=x+vmin[y];
sir[0]=r[p];
sir[1]=g[p];
sir[2]=b[p];
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=&stack[(stackpointer)*3];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi+=w;
free(r);
free(g);
free(b);
free(vmin);
free(dv);
free(stack);
CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CFRelease(m_DataRef);
free(m_PixelBuf);
return finalImage;
- (UIImage *) normalize
CGColorSpaceRef genericColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef thumbBitmapCtxt = CGBitmapContextCreate(NULL,
self.size.width,
self.size.height,
8, (4 * self.size.width),
genericColorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(genericColorSpace);
CGContextSetInterpolationQuality(thumbBitmapCtxt, kCGInterpolationDefault);
CGRect destRect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextDrawImage(thumbBitmapCtxt, destRect, self.CGImage);
CGImageRef tmpThumbImage = CGBitmapContextCreateImage(thumbBitmapCtxt);
CGContextRelease(thumbBitmapCtxt);
UIImage *result = [UIImage imageWithCGImage:tmpThumbImage];
CGImageRelease(tmpThumbImage);
return result;
@end
使用此代码模糊图像...
self.rawImage.image=[self.rawImage.image stackBlur:10.0f];
【讨论】:
不仅仅是模糊。我需要模糊那些不在滚动视图框架内的内容。这可能吗?以上是关于UIScrollview - 模糊效果 iOS的主要内容,如果未能解决你的问题,请参考以下文章