[英]how to convert UIBezierpath with shadow to UIImage without losing the shadow saturation
我正在做一個繪圖應用程序,它允許用戶在視頻幀上繪圖,所以在 UIImageView 上繪圖時,我將 Bezierpath 添加到 CAShapeLayer 並為其設置陰影路徑,效果很好,事情就是當我想要要將圖層轉換為 cg 或 uiimage 最終將是 ciimage(合成到視頻幀),UIGraphicContext 會降低陰影飽和度,就像 CAShapeLayer 中的線沒有陰影路徑,而只是一個簡單的陰影,少得多飽和度 這是使用陰影繪制時的圖像
此圖為轉成image后陰影相同的路徑
我嘗試了很多不同的方法,我可以在 SOF 或互聯網上的任何其他地方找到,所以基本上有兩種方法可以將路徑轉換為圖像(ci,ui,cg),它們都使用相同的做法,即UIGraphicContext(如果有任何其他方式請告訴我),所以我嘗試將圖層轉換為 uiimage(通過在 CGContext 上渲染它)並且還嘗試直接在上下文上繪制路徑,直接繪制路徑給了我(只是)一點比在上下文上渲染層的改進。 這是直接在上下文中繪制路徑的代碼:
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let context = UIGraphicsGetCurrentContext()!
//// Shadow Declarations
let shadow = UIColor.yellow.withAlphaComponent(1)
let shadowOffset = CGSize(width: 0, height: 0) //offset is the same as when drawing a path on CAShapeLayer
let shadowBlurRadius: CGFloat = 20
//// Bezier 2 Drawing
context.saveGState()
context.addPath(path.cgPath)
context.setShadow(offset: shadowOffset, blur: shadowBlurRadius, color: (shadow as UIColor).cgColor)
path.lineCapStyle = .round
path.lineCapStyle = .round
UIColor.white.setStroke()
path.lineWidth = 10
path.stroke(with: .color, alpha: 1.0)
//context.strokePath()
context.restoreGState()
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
我真的很感激任何幫助或提示,我可以在轉換后得到相同的陰影結果。
更新:
這是在圖層上生成陰影的代碼,它在視圖(第一張圖片)上運行良好,在渲染或繪制上下文后我需要相同的結果。
private func setTheLayer(layer: CAShapeLayer, size: Int, path: CGPath, glowing: Bool, color: CGColor) {
if glowing {
layer.path = path
layer.fillColor = nil
layer.opacity = 1.0
layer.lineWidth = CGFloat(size)
layer.lineCap = .round
layer.lineJoin = .round
layer.strokeColor = UIColor.white.cgColor
// drawing the glow shadow
layer.shadowPath = path.copy(strokingWithWidth: CGFloat(size) * 4, lineCap: .round, lineJoin: .round, miterLimit: 0)
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowColor = color
layer.shadowRadius = 5.0
layer.shadowOpacity = 0.7
} else {
layer.path = path
layer.fillColor = nil
layer.opacity = 1.0
layer.lineWidth = CGFloat(size)
layer.lineCap = .round
layer.lineJoin = .round
layer.strokeColor = color
}
}
由於我不明白的原因,當您使用圖層的render(in:)
方法時,陰影不會正確渲染。
但是,如果您的圖層被添加到視圖中,您可以使用該視圖的drawHierarchy(in: afterScreenUpdates:)
,它將忠實地渲染陰影。
這個游樂場代碼:
import UIKit
import PlaygroundSupport
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view.backgroundColor = .black
PlaygroundPage.current.liveView = view
let layer = CAShapeLayer()
let path = UIBezierPath()
path.move(to: CGPoint(x: 20, y: 50))
path.addLine(to: CGPoint(x: 180, y: 50))
layer.path = path.cgPath
layer.lineCap = .round
layer.fillColor = nil
layer.lineWidth = 4
layer.strokeColor = UIColor.white.cgColor
layer.shadowPath = path.cgPath.copy(strokingWithWidth: 16, lineCap: .round, lineJoin: .round, miterLimit: 0)
layer.shadowOffset = .zero
layer.shadowColor = UIColor.yellow.cgColor
layer.shadowRadius = 5
layer.shadowOpacity = 0.7
layer.frame = CGRect(x:0, y: 0, width: 200, height: 100)
view.layer.addSublayer(layer)
layer.shouldRasterize = true
let renderer = UIGraphicsImageRenderer(bounds: layer.bounds)
let image = renderer.image { context in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
let imageView = UIImageView(image: image)
view.addSubview(imageView)
imageView.frame.origin.y = 100
給你這個output:
不過,我很想知道為什么陰影不能正確渲染。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.