2013-06-27 94 views
0

我的目标是在此处为遮罩图像的所有不透明内容添加轮廓。从另一个图像中的不透明像素重新创建图像

Before

我目前绘制在一个单独的上下文中的图像,迭代的每个像素读取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])); 
    }]; 
    ... 
}   

After

我知道,这必须看起来像一个非常低效的技术(它需要我的台式机上,甚至处理证明的时间),这就是即使没有管理增加一个轮廓还。

任何人都可以请推荐一个更好的替代方案来实现这一目标吗?

+0

我不明白。我有很多处理图像的经验,这应该是即时 – Jason

+0

正确 - 如果您将图像绘制到上下文,为新图像创建新的上下文,并读取一个像素/上下文。写另一个上下文 - 不应该慢... @Jason,所以我同意你的看法。 –

+0

有趣。也许这是我的方法,那就是问题所在。目前,我迭代我的新图像中的每个像素,并在每次迭代中查询包含所有不透明像素坐标点的数组。这是一个运行很多次的相当大的查询。 – Ricky

回答

0

您已在所有像素上创建双循环:如果在找到像素后未设置*stopYES,则继续使用indexOfObjectsPassingTest:。也许这是什么让它如此缓慢?

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

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];