Objective-C 如何避免在具有 UIBezierPath 笔触颜色的相同颜色图像上绘图

Posted

技术标签:

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

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

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

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

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

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

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

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

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

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

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

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

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

【问题讨论】:

【参考方案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;
    

【讨论】:

它对我有用,但是当我在相册中保存相同的图像时它不起作用..请给我建议!! ***.com/questions/28358447/… 请给我一些建议【参考方案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

【讨论】:

以上是关于Objective-C 如何避免在具有 UIBezierPath 笔触颜色的相同颜色图像上绘图的主要内容,如果未能解决你的问题,请参考以下文章

如何在objective-c中比较两个具有很多属性的对象

如何将 Objective-C initXXX 方法绑定到具有相同类型参数的 Xamarin.iOS 构造函数?

使用 ARC 的 Objective-C 代表

如何从具有隐藏变量名称(参数前的_)或内部+外部(例如 foo(with bar:))的 Objective-C 调用 Swift 函数

使用objective-c块时避免泄漏的最佳实践是啥?

IOS/objective-c/core-data:如何从相关实体获取属性