如何将UIBezierPath保存到现有的UIImageView?

问题描述:

我无法弄清楚如何将我的绘制路径保存到UIImage?
我知道我必须使用UIGraphicsBeginImageContext和类似[drawImage drawInRect:CGRectMake(0,0,drawImage.size.width,drawImage.size.height)];
但我不知道把它放在我的触摸功能中。如何将UIBezierPath保存到现有的UIImageView?

我需要保存图像的每条路径,因为我希望能够在每条绘制的线后更改颜色和alpha值。
使用此代码,当我更改值时,所有行将在同一时间调整颜色和宽度。

- (id) initWithFrame:(CGRect)frame andImage: (UIImageView*) image 
{ 
    ... 
    paths = [[NSMutableArray alloc]init]; 

    drawImage = image; 
    self.backgroundColor=[UIColor clearColor]; 
    [self addSubview:drawImage]; 
} 
- (void)drawRect:(CGRect)rect 
{ 
    [brushPattern setStroke]; 
    [myPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; 
    // Drawing code 
    //[myPath stroke]; 
} 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; 
    myPath=[[UIBezierPath alloc]init]; 
    [myPath moveToPoint:[mytouch locationInView:self]]; 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; 
    [myPath addLineToPoint:[mytouch locationInView:self]]; 
    [self setNeedsDisplay]; 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

    [paths addObject:myPath]; 
    [myPath release]; 
} 

根据您先前的问题,我假设图像视图是此自定义视图对象的子视图。你需要在这个类中维护一个可变路径数组。将其初始化为touchesBegan:withEvent:并关闭路径touchesEnded:withEvent:。将路径推入数组。在每个触摸事件(开始,移动,结束)中,调用一个方法,在将触点添加到路径后更新图像视图的图像。

更新图像将涉及创建一个空的图像上下文,然后遍历数组中的所有路径和当前路径,同时抚摸它们。完成绘图后,从上下文生成图像对象并将其设置为图像。直到我们注意到每个路径可能在属性上有所不同时,我们才会很直观要处理这个问题,你应该为路径创建一个容器类,它将保存路径的属性。将该类的一个对象推入数组中的每个路径,而不是路径本身。这样你可以维护你的视图的状态。

+0

如何更新图像视图的图像?我不明白我如何在我的图像视图中放置路径。因为我只设置了一个指向该路径的点,但从不将该路径链接到该图像视图。 – madmax 2011-06-07 22:47:46

+1

已经创建了一个['sample project'](http://dl.dropbox.com/u/22783696/Beziers.zip),它会给你一个基本的想法。我将路径推入数组并在最后使用相同的笔触颜色来绘制它们。就像上面提到的那样,你将不得不创建一个复合对象来存储关于路径和路径本身的颜色信息,并将该对象推入数组中。 – 2011-06-08 00:23:53

+0

谢谢!现在我懂了。 ;-)但是当我将它传递给这个画图控制器时,我的图像视图包含了一些图纸。所以现在它会被覆盖。我如何将这些内容添加到图像上下文中,所以路径位于此图像之上? – madmax 2011-06-08 10:04:47

有一种出路和非常简单的事实,每次绘制路径对象时,您都可以将其保存为增量图像,只需在需要的地方创建它,然后在绘制其他东西之前在绘制矩形中显示此图像。

这里是示例代码:

- (void)drawBitmap 
{ 
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0); 
    [strokeColor setStroke]; 
    if (!incrementalImage) // first time draw; paint background white by ... 
    { 
     UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds]; // enclosing bitmap by a rectangle defined by another UIBezierPath object 
     [[UIColor colorWithPatternImage:[UIImage imageNamed:@"two.jpg"]] setFill]; 
     //[[UIColor whiteColor] setFill]; 
     [rectpath fill]; // filling it with white 
     NSLog(@"========== ... drawBitmap .. CALLED======="); 
    } 
    [incrementalImage drawAtPoint:CGPointZero]; 

    for(NSDictionary *_pathDict in pathArray) 
    { 
     [((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) 
     [[_pathDict valueForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; 
    } 
    incrementalImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    } 

后,只是把这种INCREAMENTAL图像中的drawRect:,让用户拥有连续拉拔的幻觉,那么你就可以节省大量的时间这一形象一点:

- (void)drawRect:(CGRect)rect 
{ 

    [incrementalImage drawInRect:rect]; 
    [[dict_path objectForKey:@"color"] setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) 

    [[dict_path objectForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; 

} 

可能是你需要修改一些代码,根据自己的need.Hope此帮助别人