我的目标是在这里为盾牌图像的所有不透明内容添加一个轮廓。
我目前正在一个单独的上下文中绘制图像,迭代每个像素以读取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]));
}];
...
}
我知道这看起来似乎是一种非常低效的技术(甚至在我的桌面计算机上进行处理所需的时间证明了这一点),甚至还没有设法添加大纲。
有人可以推荐一个更好的替代方案吗?
答案 0 :(得分: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];