【问题标题】:How to draw UIBezierPath with image, to erase image如何用图像绘制 UIBezierPath,以擦除图像
【发布时间】:2013-11-28 05:53:53
【问题描述】:

实际上我们正在开发一个绘画应用程序,

我们使用贝塞尔路径、路径数组绘制笔触。我们几乎完成了应用程序,

但是从已经绘制 Bezierpaths 的 PathsArray 中绘制笔画存在一些性能问题,例如在绘制一定数量的笔画后笔画变慢,

所以为了避免这个性能问题,我们在 sketchImage 视图后面使用了一个临时图像视图,

我们在 Top Sketch Image 视图上绘制了最近的一笔,并用 PathsArray 更新了底部的 Temperary iamge 视图,

它工作正常并且提高了性能,但是 Eraser 中存在问题..

在进行橡皮擦时,backGroun 临时图像视图仅在笔画结束时更新,

所以我们计划在橡皮擦选择时擦除图像,如何做到这一点..任何其他方式

-(void)updateTempararyBottomLayerImageView 
{
    TempararyBottomLayerImageView.frame = CGRectMake(TopLayerImageView.frame.origin.x, TopLayerImageView.frame.origin.y, TopLayerImageView.frame.size.width, TopLayerImageView.frame.size.height);

    UIGraphicsBeginImageContext(TempararyBottomLayerImageView.bounds.size);

    for ( NSDictionary *dict in pathsArray )
    {
        UIBezierPath *p = (UIBezierPath*)[dict objectForKey:@"path"];
        p.lineWidth = [[dict objectForKey:@"size"]floatValue];

        if ([[dict objectForKey:@"red"] floatValue] == 0) //When eraser selected
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
        }
        else
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
            [[UIColor colorWithRed:[[dict objectForKey:@"red"]floatValue]
                             green:[[dict objectForKey:@"green"]floatValue]
                              blue:[[dict objectForKey:@"blue"]floatValue]
                             alpha:[[dict objectForKey:@"alpha"]floatValue]] setStroke];
        }
        [p stroke];
    }

    [[UIColor colorWithRed:red green:green blue:blue alpha:opacity] setStroke];

    if(isEraser) //When eraser selected, change color as clear
    {
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
    }
    else
    {
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
    }

    if (!isTouchEnd)
        [bzierPath stroke];

    TempararyBottomLayerImageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

}


- (void) updateDrawingBoard
{

    UIGraphicsBeginImageContext(TopLayerImageView.bounds.size);

    if (pathsArray.count > 0)
    {
        NSDictionary * dict = [pathsArray lastObject];

        UIBezierPath *p ;
        @try {
            p = (UIBezierPath*)[dict objectForKey:@"path"];
        }
        @catch (NSException *exception)
        {
            NSLog(@"xxxxxxxxxxxx");
            return;
        }


        p.lineWidth = [[dict objectForKey:@"size"]floatValue];

        if ([[dict objectForKey:@"red"] floatValue] == 0) //When eraser selected
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
        }
        else
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
            [[UIColor colorWithRed:[[dict objectForKey:@"red"]floatValue]
                             green:[[dict objectForKey:@"green"]floatValue]
                              blue:[[dict objectForKey:@"blue"]floatValue]
                             alpha:[[dict objectForKey:@"alpha"]floatValue]] setStroke];
        }
        [p stroke];



        [[UIColor colorWithRed:red green:green blue:blue alpha:opacity] setStroke];

        if(isEraser) //When eraser selected, change color as clear
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
        }
        else
        {
            CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
        }

        if (!isTouchEnd)
            [bzierPath stroke];

        self.TopLayerImageView.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

    }


}


# pragma =====UITouch delegates=====
//==============================================
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if( [[event touchesForView:self.TopLayerImageView] count] == 1)
    {
        CGPoint touchPoint = [[touches anyObject] locationInView:self.TopLayerImageView];

        bzierPath = [UIBezierPath bezierPath];
        bzierPath.lineCapStyle = kCGLineCapRound;
        bzierPath.lineJoinStyle = kCGLineJoinRound;
        bzierPath.lineWidth = brushSize;
        [bzierPath moveToPoint:touchPoint];
        isTouchEnd = NO;

        UIBezierPath *tempPath = bzierPath;
        NSMutableDictionary   *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       tempPath,@"path",
                                       [NSNumber numberWithFloat:red], @"red",
                                       [NSNumber numberWithFloat:green], @"green",
                                       [NSNumber numberWithFloat:blue], @"blue",
                                       [NSNumber numberWithFloat:opacity], @"alpha",
                                       [NSNumber numberWithFloat:brushSize], @"size", nil];
        if (isEraser)
        {
            dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                    tempPath,@"path",
                    [NSNumber numberWithFloat:0], @"red",
                    [NSNumber numberWithFloat:0], @"green",
                    [NSNumber numberWithFloat:0], @"blue",
                    [NSNumber numberWithFloat:0], @"alpha",
                    [NSNumber numberWithFloat:brushSize], @"size", nil];
        }
        [pathsArray addObject:dict];

        [self updateDrawingBoard];
    }

    //To hide bottom scroll wheel where ever tap in view
    UITouch *touch = [[event allTouches] anyObject];
    if ([touch view] != bottomScrollWheel)
    {
        [self minimizeScrollWheel];
    }
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if( [[event touchesForView:self.TopLayerImageView] count] == 1)
    {
        CGPoint touchPoint = [[touches anyObject] locationInView:self.TopLayerImageView];


        [bzierPath addLineToPoint:touchPoint];
        [bzierPath moveToPoint:touchPoint];

        isTouchEnd = NO;

        [self updateDrawingBoard];
    }
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if( [[event touchesForView:self.TopLayerImageView] count] == 1)
    {


        //  NSLog(@"**********************bzierPath == \r\n %@",bzierPath);

        CGPoint touchPoint = [[touches anyObject] locationInView:self.TopLayerImageView];
        [bzierPath moveToPoint:touchPoint];

        [bzierPath addLineToPoint:touchPoint];

        //bzierPath = nil;
        isTouchEnd = YES;
        [self updateDrawingBoard];
        [self updateTempararyBottomLayerImageView];

        if (TopLayerImageView.image != nil)
        {
            [undoArray addObject:TempararyBottomLayerImageView.image];
            [redoArray removeAllObjects];
            [redoPathsArray removeAllObjects];
        }


          self.TopLayerImageView.image = nil;
        [self EnableDisableUndoRedo];
    }
}


# pragma mark =====Settings =====
//==============================
// Slider Position can be changed from left to right or right to left
-(void)sliderPositionChange
{
    if (settingsPopoverVC.index == 0)
    {
        if (iOS7)
            [sliderView setFrame:CGRectMake(19, 128, 100, 357)];
        else
            [sliderView setFrame:CGRectMake(19, 108, 100, 357)];
    }
    else if(settingsPopoverVC.index == 1)
    {
        if (iOS7)
            [sliderView setFrame:CGRectMake(900, 128, 100, 357)];
        else
            [sliderView setFrame:CGRectMake(900, 108, 100, 357)];

    }
}

【问题讨论】:

  • 你试过 [self setNeedDisplay]
  • 我不知道与 [self setNeedDisplay] 完全相关;你能详细解释一下吗?

标签: iphone objective-c uiimageview uibezierpath


【解决方案1】:

下面的链接是你了解的

stack over flow - setneedslayout

SetNeedDisplay

谢谢

【讨论】:

    猜你喜欢
    • 2011-12-20
    • 2023-03-16
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2015-12-09
    相关资源
    最近更新 更多