0

我的目标是在此处为盾牌图像的所有不透明内容添加轮廓。

前

我目前正在单独的上下文中绘制图像,遍历每个像素以读取 alpha 值。

unsigned char * pixels = malloc((image.width * image.height));
CGContextRef context = CGBitmapContextCreate(pixels, image.size.width, image.size.height, 8, image.size.width, NULL, kCGImageAlphaOnly);

完成此操作后,我将拥有一个包含不透明像素所在的每个 CGPoint 的数组。然后我创建一个相同大小的新图像并将每个像素都涂成红色。

char * rgba = (char *)malloc(size.width * size.height * 4);
CGPoint pixelInQuestion = CGPointZero;
for (int i = 0; i < size.width * size.height; ++i)
{
    ...
    NSInteger locationOfOpaquePixel = [opaquePixels indexOfObjectPassingTest:^BOOL(NSValue *pointValue, NSUInteger idx, BOOL *stop) {
            return (CGPointEqualToPoint(pixelInQuestion, [pointValue CGPointValue]));
    }];
    ...
}           

后

我知道这看起来一定是一种效率极低的技术(即使在我的台式机上处理所需的时间也证明了这一点),甚至还没有设法添加大纲。

谁能推荐一个更好的替代方案来实现这一目标?

4

1 回答 1

0

您已经在所有像素上创建了一个双循环:indexOfObjectsPassingTest:如果您在找到像素后未设置*stop为,则继续。YES也许这就是让它如此缓慢的原因?

我的方法是在一个方向添加阴影并绘制,然后在另一个方向添加阴影并绘制。

CGFloat width = image.size.width;
CGFloat height = image.size.height;
UIGraphicsBeginImageContext(CGSizeMake(width, height));
CGContextRef context = UIGraphicsGetCurrentContext();


// shadow in one direction
CGSize offset = CGSizeMake(2,2);
CGFloat blur = 0;
CGColorRef color = [UIColor blackColor].CGColor;
CGContextSetShadowWithColor(context, offset, blur, color);   
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage);

// shadow in the other direction
CGSize offset2 = CGSizeMake(-2,-2);
CGContextSetShadowWithColor ( context, offset2, blur, color);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage);

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRelease(context);

另一种方法是绘制缩放图像并将其与黑色填充混合,然后在顶部绘制原始图像:

CGRect imageFrame = CGRectMake(105, 20, 108, 159);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageFrame];
NSLog(@"imageView=%@", imageView);
UIImage *image = [UIImage imageNamed:@"mapicon-1.png"];
[imageView setImage:image];
[self.view addSubview:imageView];


CGRect newImageFrame = CGRectInset(imageFrame, -20, -20);
CGRect newImageBounds = CGRectMake(0, 0, newImageFrame.size.width, newImageFrame.size.height);
UIGraphicsBeginImageContext(newImageFrame.size);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, newImageBounds.size.height);
CGContextScaleCTM(context, 1, -1);

CGContextSaveGState(context);
CGContextDrawImage(context, newImageBounds, image.CGImage);
CGContextSetBlendMode(context, kCGBlendModeSourceAtop);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillRect(context, newImageBounds);
CGContextRestoreGState(context);

CGContextDrawImage(context, CGRectInset(newImageBounds, 20, 20), image.CGImage);

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

UIImageView *newImageView = [[UIImageView alloc] initWithFrame:CGRectMake(105, 210, 108, 159)];
[newImageView setImage:newImage];
[self.view addSubview:newImageView];
于 2013-06-27T06:48:21.930 回答