2016-07-03 9 views
0

Я пытаюсь найти более быстрый способ генерации изображения Gaussian Blur, этот blog отлично работает с большей частью изображения.UIImage Gaussian Blur с vImage

Но когда изображение имеет прозрачный backgroudcolor, то размытое изображение выглядит плохо

ниже код копируется из блога:

-(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 category,
, но эффект от этой категории больше похож на Frosted glass вместо Gaussian Blur.

Blur in Core Image отлично работает, но он настолько медленный, как способ vImage.

GPUImage также медленнее, чем vImage.

Пожалуйста, помогите мне изменить код vImage выше, Я пробовал много и напишу код с демо here;

:)

+0

Наконец, я решаю его простым преобразованием изображения в .png для удаления альфа-канала 'UIImage * inputImage = [UIImage imageWithData: UIImageJPEGRepresentation (img, 1.0)];' –

+0

Прозрачное изображение с размытым результатом здесь http: // i. stack.imgur.com/o1iVy.png, pardon me, у меня недостаточно репутации, чтобы опубликовать изображение –

+0

Я надеюсь, что результат будет таким, http://i.stack.imgur.com/RZJ6V.png –

ответ

0

Было бы полезно, чтобы увидеть, что выглядит плохо о нем.

Если это только области рядом с прозрачными областями, вы можете попытаться предварительно воспроизвести изображение в первую очередь. Это позволит сохранить бессмысленные цвета в полностью прозрачных областях от кровотечения до остальной части изображения.

+0

Я добавляю образ для моего вопроса, я попытался удалить прозрачные области, перерисовывая его с помощью 'UIGraphicsBeginImageContextWithOptions', чтобы создать новое изображение с белым фоном, но все равно не wok. Затем я попытался использовать '[UIImage imageWithData: UIImageJPEGRepresentation (img, 1.0)];' для передачи изображения из формата 'png' в формат' jpeg' для удаления любого альфа-канала, это работает, но выглядит неэффективным. С нетерпением ждем вашего ответа ~ –

+0

Существует ряд функций vImageFlatten ..., которые призваны сделать изображения непрозрачными. Тем не менее, я действительно думаю, что вы должны попробовать просто предварительно умножить изображение по его альфа-каналу, чтобы убедиться, что это решает проблему. Меньшая альфа-информация уничтожается таким образом. См. VImagePremultiplyData ... –

0

Вы также могли бы сделать что-то вроде:

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

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

, чтобы избавиться от альфа. Если вам нужна цепочка с другими CIFilter, это будет более эффективно.

+0

Благодарим вас за ответ, я обновляю свой вопрос с помощью изображений. Я пробовал ваш ответ, но не работал, я использую '[UIImage imageWithData: UIImageJPEGRepresentation (img, 1.0)];' чтобы сделать изображение непрозрачным, это работает, но не эффективно, любая идея лучше? ~ –