用户使用自定义笔尖或笔触图像绘制线/路径? [迅速|目标C | iOS]

问题描述

用户画一条线和虚线很简单。我可以通过以下方式做到这一点:

            context.addpath(path)
            context.setLineCap(.round)
            context.setlinewidth(action.strokeWidth)
            context.setLineDash(phase: 0,lengths: [6,9])
            context.setstrokeColor(action.color.cgColor)
            context.setBlendMode(.normal)

我要完成的工作是让用户生成带有自定义画笔笔尖或图案的线/曲线图。我尝试做诸如colorWithPatternImage之类的事情,但这不能解决我的问题,因为它所做的只是用纹理图像图案而不是线条本身填充视图的背景。像这样:

我要完成的笔触的示例图像:

enter image description here

您对我如何完成此操作有任何建议?非常感谢!

解决方法

我强烈建议您阅读getlooseleaf,因为有几种解决方案。有些涉及着色器,有些则用于CGPatternDrawPatternCallback函数,这里有一个stackoverflow discussion如何快速实现着色

,

我正在做一个包含自由手绘功能的项目,我看到没有资源或示例来学习如何制作自定义画笔,然后在研究了很多关于核心图形的主题并花了几天时间进行测试后,我发现了一个用于创建自定义画笔(如喷雾或任何您想要的图案)的解决方案。

所有这些画笔都可以用 CGLayer 绘制。此操作的逻辑不是进行复杂的数学运算和计算像素,只需在此类图层上绘制您的图案图像并将此人传递给您的 drawing context,您就会看到您想要的。在给出和示例代码让您更好地理解之前,让我与您分享这些信息...

苹果说:

不再推荐使用CGLayer(因为它不稳定)

这就是为什么在将其用于商业项目之前要三思而后行。

仅供参考:此代码未经测试,因此如果有问题,请在您身边更正,因为我的目的只是分享我在此主题上的知识。

private func drawWithCustomBrush(brushSize size: CGSize,brushPattern pattern: UIImage,drawAtPoint atPoint: CGPoint) -> UIImage? {
    
    // Create drawing context and adjust it's settings
    let canvasSize = view.bounds.size
    UIGraphicsBeginImageContext(canvasSize) // Preferred options is much more faster than custom options
    guard let context = UIGraphicsGetCurrentContext() else { return nil }
    context.interpolationQuality = .high
    context.setAlpha(1.0)
    
    // Optionally you can draw background image
    // YOUR_BG_IMAGE.draw(in: CGRect(origin: .zero,size: canvasSize))
    
    // Create CGLayer with drawing context and draw your pattern with context that CGLayer gives us
    let layer = CGLayer(context,size: size,auxiliaryInfo: nil)
    // Get drawing context from the layer for drawing pattern on this layer
    guard let layerContext = layer?.context else { return nil }
    layerContext.interpolationQuality = .high
    // Draw pattern (as cgImage) on layer with layer context
    layerContext.draw(pattern.cgImage!,in: CGRect(origin: .zero,size: size))
    // Calculate pattern layer position or rect
    let layerRect = CGRect(origin: CGPoint(x: atPoint.x - size.width / 2,y: atPoint.y - size.height / 2),size: size)
    // Now draw the layer our canvas by using drawing context [Not Layer Context!]
    context.draw(layer!,in: layerRect)
    
    // Create result image from current drawing context
    guard let finalImage = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
    // Clean up the drawing environment
    UIGraphicsEndImageContext()
    // Return your new image
    return finalImage
}

奖励:-

为了摆脱不需要的不同颜色的图案副本,请使用此 UIImage 扩展功能为您的图案重新着色。

func maskWithColor(color: UIColor) -> UIImage? {
    let maskImage = cgImage!
    
    let width = size.width
    let height = size.height
    let bounds = CGRect(x: 0,y: 0,width: width,height: height)
    
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
    let context = CGContext(data: nil,width: Int(width),height: Int(height),bitsPerComponent: 8,bytesPerRow: 0,space: colorSpace,bitmapInfo: bitmapInfo.rawValue)!
    
    context.clip(to: bounds,mask: maskImage)
    context.setFillColor(color.cgColor)
    context.fill(bounds)
    
    if let cgImage = context.makeImage() {
        let coloredImage = UIImage(cgImage: cgImage)
        return coloredImage
    } else {
        return nil
    }
}

如您所见,使用 CGLayer 是多么容易。现在,您只需传递一个 UIImage [它应该是 png] 即可根据需要创建自定义画笔。

快乐编码...