3

画像の周りに黒い輪郭を描くために多くの方法を試しました。
これは私が望む結果の例です:

ここに画像の説明を入力

誰かが私にそれをどうすればよいか教えてもらえますか? または私に例を教えてください?

編集:私はここで立ち往生しています:誰かが私がそれを終わらせるのを手伝ってくれますか?私がしたことは、影のある白の下に黒い色で別の形を作り、それをすべて黒で塗りつぶして輪郭のようにすることでした-しかし、影を作る最後の重要な部分を作る方法がわかりません。全体が黒くなるように塗りつぶします。

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

1 に答える 1

0

そのための組み込み API はありません。自分で行うか、ライブラリを見つける必要があります。ただし、画像に影を付けて描画することで、効果を「偽造」することができます。影は任意の色にすることができ、影のように見える必要はありません。これが最も簡単な方法です。

それ以外は、ラスター イメージをベクトル化し、そのパスをストロークすることができます。コア イメージのエッジ検出フィルターはそのために役立ちますが、達成するのが難しいことが判明する可能性があります。

于 2012-10-20T12:44:56.697 に答える