2012-01-06 68 views
7

我试过高斯模糊和检查了所有的问题在stackoverflow但没有人解决了我的崩溃issue.Please帮助是有任何其他方式来模糊图像以外的高斯模糊算法。我的图像大小是768x1024,循环迭代2 * 1024 * 768次,这是不可行的。模糊滑块变化UIImage

CGContextRef NYXImageCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow) 
{ 
/// Use the generic RGB color space 
/// We avoid the NULL check because CGColorSpaceRelease() NULL check the value anyway, and worst case scenario = fail to create context 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

/// Create the bitmap context, we want pre-multiplied ARGB, 8-bits per component 
CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8/*Bits per component*/, bytesPerRow, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); 

CGColorSpaceRelease(colorSpace); 

return bmContext; 
} 



-(UIImage*)blurredImageUsingGaussFactor:(NSUInteger)gaussFactor andPixelRadius:(NSUInteger)pixelRadius 
{ 
CGImageRef cgImage = self.CGImage; 
const size_t originalWidth = CGImageGetWidth(cgImage); 
const size_t originalHeight = CGImageGetHeight(cgImage); 
const size_t bytesPerRow = originalWidth * 4; 
CGContextRef context = NYXImageCreateARGBBitmapContext(originalWidth, originalHeight, bytesPerRow); 
if (!context) 
    return nil; 

unsigned char *srcData, *destData, *finalData; 

size_t width = CGBitmapContextGetWidth(context); 
size_t height = CGBitmapContextGetHeight(context); 
size_t bpr = CGBitmapContextGetBytesPerRow(context); 
size_t bpp = CGBitmapContextGetBitsPerPixel(context)/8; 
CGRect rect = {{0.0f, 0.0f}, {width, height}}; 

CGContextDrawImage(context, rect, cgImage); 

// Now we can get a pointer to the image data associated with the bitmap 
// context. 
srcData = (unsigned char*)CGBitmapContextGetData(context); 
if (srcData != NULL) 
{ 
    size_t dataSize = bpr * height; 
    finalData = malloc(dataSize); 
    destData = malloc(dataSize); 
    memcpy(finalData, srcData, dataSize); 
    memcpy(destData, srcData, dataSize); 

    int sums[gaussFactor]; 
    size_t i, /*x, y,*/ k; 
    int gauss_sum = 0; 
    size_t radius = pixelRadius * 2 + 1; 
    int *gauss_fact = malloc(radius * sizeof(int)); 

    for (i = 0; i < pixelRadius; i++) 
    { 
     gauss_fact[i] = 1 + (gaussFactor * i); 
     gauss_fact[radius - (i + 1)] = 1 + (gaussFactor * i); 
     gauss_sum += (gauss_fact[i] + gauss_fact[radius - (i + 1)]); 
    } 
    gauss_fact[(radius - 1)/2] = 1 + (gaussFactor*pixelRadius); 
    gauss_sum += gauss_fact[(radius - 1)/2]; 

    unsigned char *p1, *p2, *p3; 

    for (size_t y = 0; y < height; y++) 
    { 
     for (size_t x = 0; x < width; x++) 
     { 
      p1 = srcData + bpp * (y * width + x); 
      p2 = destData + bpp * (y * width + x); 

      for (i = 0; i < gaussFactor; i++) 
       sums[i] = 0; 

      for (k = 0; k < radius ; k++) 
      { 
       if ((y - ((radius - 1) >> 1) + k) < height) 
        p1 = srcData + bpp * ((y - ((radius - 1) >> 1) + k) * width + x); 
       else 
        p1 = srcData + bpp * (y * width + x); 

       for (i = 0; i < bpp; i++) 
        sums[i] += p1[i] * gauss_fact[k]; 

      } 
      for (i = 0; i < bpp; i++) 
       p2[i] = sums[i]/gauss_sum; 
     } 
    } 
    for (size_t y = 0; y < height; y++) 
    { 
     for (size_t x = 0; x < width; x++) 
     { 
      p2 = destData + bpp * (y * width + x); 
      p3 = finalData + bpp * (y * width + x); 

      for (i = 0; i < gaussFactor; i++) 
       sums[i] = 0; 

      for(k = 0; k < radius ; k++) 
      { 
       if ((x - ((radius - 1) >> 1) + k) < width) 
        p1 = srcData + bpp * (y * width + (x - ((radius - 1) >> 1) + k)); 
       else 
        p1 = srcData + bpp * (y * width + x); 

       for (i = 0; i < bpp; i++) 
        sums[i] += p2[i] * gauss_fact[k]; 

      } 
      for (i = 0; i < bpp; i++) 
      { 
       p3[i] = sums[i]/gauss_sum; 
      } 
     } 
    } 
} 

size_t bitmapByteCount = bpr * height; 

///////Here was the problem.. you had given srcData instead of destData.. Rest all 
//were perfect... 
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, destData, bitmapByteCount, NULL); 

CGImageRef blurredImageRef = CGImageCreate(width, height, CGBitmapContextGetBitsPerComponent(context), CGBitmapContextGetBitsPerPixel(context), CGBitmapContextGetBytesPerRow(context), CGBitmapContextGetColorSpace(context), CGBitmapContextGetBitmapInfo(context), dataProvider, NULL, true, kCGRenderingIntentDefault); 

CGDataProviderRelease(dataProvider); 
CGContextRelease(context); 
if (destData) 
    free(destData); 
if (finalData) 
    free(finalData); 

UIImage* retUIImage = [UIImage imageWithCGImage:blurredImageRef]; 

CGImageRelease(blurredImageRef); 

return retUIImage; 
} 
+0

后的代码为您的高斯模糊的实现 - 这样你可以得到修复它的帮助 – 2012-01-06 13:33:45

+0

好吧,我只是发布我的代码。 – Leena 2012-01-06 13:43:16

+0

检查此SO问题:http://stackoverflow.com/questions/1356250/iphone-blur-uiimage – 2012-01-06 15:41:56

回答

15

我对UIImage做了一个小的StackBlur扩展。 StackBlur接近GaussianBlur,但速度更快。

在检查它:https://github.com/tomsoft1/StackBluriOS


小小的音符 ...有一个错字只是对自述,“正常化”的“正常化”

+0

感谢它真的工作正常,顺利.... – Leena 2012-02-07 09:47:54

+0

它帮助我toooo.Thanks很多 – Meet 2012-02-07 09:48:47

+1

伟大的作品,你知道任何处理透明度的StackBlur实现吗? – mmc 2012-06-07 22:41:13

2

不确定如何模糊图像。 这可能有助于你想要blur an UIImageView or any view

UIView *myView = self.theImageView; 
    CALayer *layer = [myView layer]; 
    [layer setRasterizationScale:0.25]; 
    [layer setShouldRasterize:YES]; 

可以通过设置光栅化规模回复原为1

[layer setRasterizationScale:1.0]; 

UPDATE:

的下面苹果示例代码包括模糊/锐利的效果。 (使用Open GL) 看看有没有什么帮助,http://developer.apple.com/library/ios/#samplecode/GLImageProcessing/Introduction/Intro.html

+0

我想保存模糊的图像。 – Leena 2012-01-06 13:48:19

+0

k,添加了示例代码的链接。看看是否有帮助你。 – sElanthiraiyan 2012-01-06 13:54:37

+0

我也尝试过,但它不如高斯模糊 – Leena 2012-01-06 13:57:22

1

你可能想要的是一个Box Blur算法。它比高斯模糊快大约10倍,并且产生很好的结果。我有在Android上运行的代码,我只是还没有将它移植到iOS。这里是source

只需要大约10分钟即可移植到iOS。这些函数将按原样工作,您只需访问图像字节(如您在上面的源代码中所做的那样)并将它们提供给函数。

+0

好吧我试试看,谢谢你的帮助。 – Leena 2012-01-07 05:12:48

+0

Box Blur可作为Core Image的一部分。 – Abizern 2012-01-07 11:43:39

+1

box blur仅适用于mac检查此链接:-http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/uid/ TP30000136-SW69 – Leena 2012-01-07 11:54:32