UIImage高斯模糊与vImage

时间:2016-07-03 09:37:07

标签: ios blur gaussian core-image vimage

我正在尝试找到一种更快的方式来生成Gaussian Blur图片,这个blog适用于大部分图片。

但是当图像具有透明的背景色时,模糊的图像看起来很糟糕

以下代码是从博客中复制的:

-(UIImage *)vImageBlurWithNumber:(CGFloat)blur
{
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 100);
    boxSize = boxSize - (boxSize % 2) + 1;

    CGImageRef img = self.CGImage;

    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;

    void *pixelBuffer;

    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);

    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);

    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);

    pixelBuffer = malloc(CGImageGetBytesPerRow(img) *
                     CGImageGetHeight(img));

    if(pixelBuffer == NULL)
        NSLog(@"No pixelbuffer");

    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);

    // may be i should modify last 2 parameter below ,how ?
    error = vImageBoxConvolve_ARGB8888(&inBuffer,
                                   &outBuffer,
                                   NULL,
                                   0,
                                   0,
                                   boxSize,
                                   boxSize,
                                   NULL,
                                   kvImageEdgeExtend); //        kvImageBackgroundColorFill ?



    if (error) {
        NSLog(@"error from convolution %ld", error);
    }

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(
                                         outBuffer.data,
                                         outBuffer.width,
                                         outBuffer.height,
                                         8,
                                         outBuffer.rowBytes,
                                         colorSpace,
                                         kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];

    //clean up
//    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);

    free(pixelBuffer);
    CFRelease(inBitmapData);

    CGColorSpaceRelease(colorSpace);
    CGImageRelease(imageRef);

    return returnImage;
}

我尝试了另一种方法来制作Gaussian Blur效果,
使用Apple WWDC 2013 UIImage-ImageEffects类别,
但此类别的效果更像Frosted glass而不是Gaussian Blur

Blur in Core Image工作正常,但它比vImage方式慢。

GPUImage也比vImage方式慢。

请帮我修改上面的vImage代码, 我已经尝试了很多,并使用demo here;

发布代码

:)

2 个答案:

答案 0 :(得分:0)

看看它看起来很糟糕会很有用。

如果它只是透明区域附近的区域,您可能会尝试首先对图像进行预乘。这将使完全透明区域中无意义的颜色不会渗透到图像的其余部分。

答案 1 :(得分:0)

您还可以执行以下操作:

var noAlpha = CIVector(x: 0, y: 0, z: 0, w: 1)

image.imageByApplyingFilter("CIColorMatrix", 
    withInputParameters: ["inputAVector": noAlpha])

摆脱阿尔法。如果您需要与其他CIFilter链接,这将更有效。