Translate

Thursday 20 September 2012

how to make Blur effect ?



Task : image blur in ios by this category file....


Image coding : 

.h file:

#import <Foundation/Foundation.h>


@interface UIImage (StackBlur)
    - (UIImage*) stackBlur:(NSUInteger)radius;
    - (UIImage *) normalize ;

@end

.m file:
#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
 
 the call will be ...
 self.rawImage.image=[self.rawImage.image stackBlur:10.0f];

the cloud link here

No comments:

Post a Comment