UIScrollview - 模糊效果iOS

时间:2012-09-20 02:51:30

标签: ios xcode uiview calayer

我有分页UIScrollview。 UIScrollview是所选用户的选择。我应该模糊那些不在scrollview框架内的页面。有什么建议吗?以下是已实施的UIScrollview的screenshot。具有低alpha分量的黑匣子将被其他页面上的模糊效果所取代。

1 个答案:

答案 0 :(得分:0)

我通过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];