Как нарисовать контур / обводку вокруг UIImage (*.png) - Пример внутри

Я перепробовал много способов нарисовать черный контур вокруг изображения.
Это пример результата, который я хочу:

Может кто-нибудь, пожалуйста, дайте мне знать, как мне это сделать? или приведите пример?

Редактировать: я застрял здесь: может кто-нибудь, пожалуйста, помогите мне закончить это? Я сделал другую фигуру черного цвета под белым с тенью, а затем залил все черным, чтобы она была похожа на контур - но я не могу понять, как сделать последнюю и важную часть создания тени и заполните его, чтобы все было черным.

- (IBAction)addStroke:(id)sender{

    [iconStrokeTest setImage:[self makeIconStroke:icon.imageView.image]];

}

- (UIImage *)makeIconStroke:(UIImage *)image{
    CGImageRef originalImage = [image CGImage];
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
                                                       CGImageGetWidth(originalImage),
                                                       CGImageGetHeight(originalImage),
                                                       8,
                                                       CGImageGetWidth(originalImage)*4,
                                                       colorSpace,
                                                       kCGImageAlphaPremultipliedLast);

    CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGBitmapContextGetWidth(bitmapContext), CGBitmapContextGetHeight(bitmapContext)), originalImage);

    CGImageRef finalMaskImage = [self createMaskWithImageAlpha:bitmapContext];

    UIImage *result = [UIImage imageWithCGImage:finalMaskImage];

    CGContextRelease(bitmapContext);
    CGImageRelease(finalMaskImage);

    // begin a new image context, to draw our colored image onto
    UIGraphicsBeginImageContext(result.size);

    // get a reference to that context we created
    CGContextRef context = UIGraphicsGetCurrentContext();

    // set the fill color
    [[UIColor blackColor] setFill];

    // translate/flip the graphics context (for transforming from CG* coords to UI* coords
    CGContextTranslateCTM(context, 0, result.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // set the blend mode to color burn, and the original image
    CGContextSetBlendMode(context, kCGBlendModeColorBurn);
    CGRect rect = CGRectMake(0, 0, result.size.width, result.size.height);
    CGContextDrawImage(context, rect, result.CGImage);

    // set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
    CGContextClipToMask(context, rect, result.CGImage);
    CGContextAddRect(context, rect);
    CGContextDrawPath(context,kCGPathFill);

    // generate a new UIImage from the graphics context we drew onto
    UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //return the color-burned image
    return coloredImg;

}

- (CGImageRef)createMaskWithImageAlpha:(CGContextRef)originalImageContext {

    UInt8 *data = (UInt8 *)CGBitmapContextGetData(originalImageContext);

    float width = CGBitmapContextGetBytesPerRow(originalImageContext) / 4;
    float height = CGBitmapContextGetHeight(originalImageContext);

    int strideLength = ROUND_UP(width * 1, 4);
    unsigned char * alphaData = (unsigned char * )calloc(strideLength * height, 1);
    CGContextRef alphaOnlyContext = CGBitmapContextCreate(alphaData,
                                                          width,
                                                          height,
                                                          8,
                                                          strideLength,
                                                          NULL,
                                                          kCGImageAlphaOnly);

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            unsigned char val = data[y*(int)width*4 + x*4 + 3];
            val = 255 - val;
            alphaData[y*strideLength + x] = val;
        }
    }

    CGImageRef alphaMaskImage = CGBitmapContextCreateImage(alphaOnlyContext);
    CGContextRelease(alphaOnlyContext);
    free(alphaData);

    // Make a mask
    CGImageRef finalMaskImage = CGImageMaskCreate(CGImageGetWidth(alphaMaskImage),
                                                  CGImageGetHeight(alphaMaskImage),
                                                  CGImageGetBitsPerComponent(alphaMaskImage),
                                                  CGImageGetBitsPerPixel(alphaMaskImage),
                                                  CGImageGetBytesPerRow(alphaMaskImage),
                                                  CGImageGetDataProvider(alphaMaskImage),     NULL, false);
    CGImageRelease(alphaMaskImage);

    return finalMaskImage;
} 

1 ответ

Ну, для этого нет встроенного API. Вам придется сделать это самостоятельно или найти для этого библиотеку. Но вы можете "подделать" эффект, рисуя изображение с тенью. Обратите внимание, что тени могут быть любого цвета, они не должны выглядеть как тени. Это был бы самый простой способ.

Кроме этого вы можете векторизовать растровое изображение и обвести этот путь. Фильтр обнаружения краев основного изображения поможет в этом, но он может оказаться трудным для выполнения.

Другие вопросы по тегам