在滑动条改变时模糊UIImage

7

我尝试了高斯模糊并查看了stackoverflow上的所有问题,但没有解决我的崩溃问题。请帮忙提供其他方法来对图像进行模糊处理,除了高斯模糊算法之外。我的图像大小为768x1024,循环迭代了2*1024*768次,这是不可行的。

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;
}

发布你的高斯模糊实现的代码 - 这样你就可以获得帮助来修复它。 - Paul R
请查看这个SO问题:https://dev59.com/-0nSa4cB1Zd3GeqPLSIt - Krishna K
我发现这个网址:http://code.google.com/p/simple-iphone-image-processing/ - Reefaq
尝试使用GPUImage https://github.com/BradLarson/GPUImage,这是一个非常快速的图像处理库。 - Mrug
3个回答

15

我为 UIImage 制作了一个小的 StackBlur 扩展程序。StackBlur 接近高斯模糊但速度更快。

请查看:https://github.com/tomsoft1/StackBluriOS


小提示... 在那个自述文件上有一个拼写错误,应该是 "normalize" 而不是 "normalized"。


1
非常好,你知道在iOS上有没有处理透明度的StackBlur实现吗? - mmc
当我运行上述 stackBlur 代码时,程序崩溃了。 - Uttam
@tomsoft:这个答案中已经编辑了一个错别字/错误报告,但我不确定它是否属于这里。能否在仓库上采取行动,以便可以在此处删除? - halfer

2

如果您不确定如何模糊图像,以下内容可能会有所帮助,如果您想要模糊UIImageView或任何视图

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

您可以通过将光栅化比例设置回1来撤销它。

[layer setRasterizationScale:1.0];

更新:

以下是苹果公司的示例代码,其中包括模糊/锐化效果。(使用Open GL) 请查看是否有帮助:http://developer.apple.com/library/ios/#samplecode/GLImageProcessing/Introduction/Intro.html


我想保存我的模糊图像。 - Leena

1

你可能需要的是一个盒状模糊算法。它比高斯模糊快大约10倍,并且产生很好的效果。我已经在Android上运行了代码,只是还没有将其移植到iOS上。这里是源代码

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


盒状模糊是Core Image的一部分。 - Abizern
1
盒状模糊仅适用于Mac,请查看此链接:-http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/uid/TP30000136-SW69 - Leena
你可以尝试使用vImageBoxConvolve_ARGB8888。还有一种看起来更好的帐篷滤镜。 - Ian Ollmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接