0

我已经尝试了高斯模糊并检查了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;
}

提前致谢

4

2 回答 2

2

查看来自 WWDC 2012 的视频。

高斯模糊是 CoreImage 中的内置过滤器。

会议 510。

也看看这里...

https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/CoreImaging/ci_intro/ci_intro.html

(你想要的部分是处理图像)

于 2012-12-17T09:15:12.307 回答
1

此示例适用于 UIImage 的小型 StackBlur 扩展。StackBlur 接近 GaussianBlur 但要快得多。

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

于 2012-12-17T09:14:14.587 回答