问题描述
用户画一条线和虚线很简单。我可以通过以下方式做到这一点:
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之类的事情,但这不能解决我的问题,因为它所做的只是用纹理图像图案而不是线条本身填充视图的背景。像这样:
我要完成的笔触的示例图像:
您对我如何完成此操作有任何建议?非常感谢!
解决方法
我强烈建议您阅读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] 即可根据需要创建自定义画笔。
快乐编码...