【问题标题】:Objective-C How to avoid drawing on same color image having stroke color of UIBezierPathObjective-C 如何避免在具有 UIBezierPath 笔触颜色的相同颜色图像上绘图
【发布时间】:2013-11-28 10:21:32
【问题描述】:

我们正在使用UIBezierPath 开发一个绘画应用程序,

我们使用贝塞尔路径绘制笔触,

使用蓝色 RGB 值和 0.5 Alpha 用于透明描边

使用路径数组..我们几乎完成了应用程序,

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

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

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

它工作得很好并且提高了性能,但是有一个问题

由于所有笔画都保存为图像并且我们尝试绘制另一张图像,因此笔画会加倍并增加重叠点的不透明度

实际上如果我们只使用 bezierPAths 数组,我们可以避免使用 kCGBlendModeCopy

但由于我们将笔画更新为图像,因此无法使用 kCGBlendModeCopy

那么有什么办法可以避免在同一油漆上出现中风

【问题讨论】:

    标签: iphone objective-c uibezierpath


    【解决方案1】:

    您可以通过两个图像视图来实现所需的效果,其中一个是风景照片,在此之上,还有另一个我们要在其上绘制的图像视图。但是,与其使用 0.5 的 alpha 进行绘制,不如使用 1.0 的 alpha 绘制 UIBezierPath,而是在自己的 alpha 为 0.5 的图像视图上进行。

    - (void)handlePan:(UIPanGestureRecognizer *)gesture
    {
        static UIBezierPath *bezierPath = nil;
        static CAShapeLayer *shapeLayer = nil;
    
        if (gesture.state == UIGestureRecognizerStateBegan) {
            bezierPath = [UIBezierPath bezierPath];
            [bezierPath moveToPoint:[gesture locationInView:gesture.view]];
            shapeLayer = [CAShapeLayer layer];
            shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
            shapeLayer.lineWidth = 40.0;
            shapeLayer.fillColor = [[UIColor clearColor] CGColor];
            shapeLayer.lineCap = kCALineCapRound;
            shapeLayer.lineJoin = kCALineJoinRound;
            [self.drawImageView.layer addSublayer:shapeLayer];
        } else if (gesture.state == UIGestureRecognizerStateChanged) {
            [bezierPath addLineToPoint:[gesture locationInView:gesture.view]];
            shapeLayer.path = [bezierPath CGPath];
        } else if (gesture.state == UIGestureRecognizerStateEnded) {
            CGFloat saveAlpha = self.drawImageView.alpha;  // save current alpha for future reference
            self.drawImageView.alpha = 1.0;                // bring alpha back to 1.0 for the purposes of saving image
    
            // grab image
    
            UIGraphicsBeginImageContextWithOptions(self.drawImageView.bounds.size, NO, 0);
            if ([self.drawImageView respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
                [self.drawImageView drawViewHierarchyInRect:self.drawImageView.bounds afterScreenUpdates:YES]; // iOS7+
            else
                [self.drawImageView.layer renderInContext:UIGraphicsGetCurrentContext()]; // pre iOS7
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
    
            self.drawImageView.image = image;             // use new image
            self.drawImageView.alpha = saveAlpha;         // reduce alpha back to what it was
    
            [shapeLayer removeFromSuperlayer];            // get rid of shape layer
            shapeLayer = nil;
            bezierPath = nil;
        }
    }
    

    【讨论】:

    【解决方案2】:
    - (UIImage*)addImage:(UIImage *)image secondImage:(UIImage *)image2
    {
        UIGraphicsBeginImageContext(image.size);
        [image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
    
        [image2 drawInRect:CGRectMake(0,0,image.size.width,image.size.height) blendMode:kCGBlendModeXOR alpha:1.0];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return newImage;
    }
    

    添加两个 UIImage 使用上面的代码。在blendMode 中使用kCGBlendModeXOR

    【讨论】:

      猜你喜欢
      • 2021-09-16
      • 1970-01-01
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2014-05-26
      • 2021-04-12
      相关资源
      最近更新 更多