如何在不丢失阴影饱和度的情况下将带有阴影的 UIBezierpath 转换为 UIImage
how to convert UIBezierpath with shadow to UIImage without losing the shadow saturation
我正在做一个绘图应用程序,它允许用户在视频帧上绘图,所以在 UIImageView 上绘图时,我将 Bezierpath 添加到 CAShapeLayer 并为其设置阴影路径,效果很好,事情是当我想将层转换为 cg 或 ui 图像最终将是 ci 图像(组成视频帧)时,UIGraphicContext 降低阴影饱和度,例如 CAShapeLayer 中的线没有阴影路径,只是一个饱和度低得多的简单阴影
这是用阴影绘制时的图像
此图为转图后相同阴影的路径
我已经尝试了很多不同的方法,我可以在 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
我真的很感激ci任何帮助或暗示我在转换后可以获得相同的阴影结果。
已更新:
这是在图层上生成阴影的代码,在视图上效果很好(第一张图片)
在上下文中渲染或绘制后我需要相同的结果。
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
给你这个输出:
不过,我很想知道为什么阴影无法正确渲染。
我正在做一个绘图应用程序,它允许用户在视频帧上绘图,所以在 UIImageView 上绘图时,我将 Bezierpath 添加到 CAShapeLayer 并为其设置阴影路径,效果很好,事情是当我想将层转换为 cg 或 ui 图像最终将是 ci 图像(组成视频帧)时,UIGraphicContext 降低阴影饱和度,例如 CAShapeLayer 中的线没有阴影路径,只是一个饱和度低得多的简单阴影 这是用阴影绘制时的图像
此图为转图后相同阴影的路径
我已经尝试了很多不同的方法,我可以在 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
我真的很感激ci任何帮助或暗示我在转换后可以获得相同的阴影结果。
已更新:
这是在图层上生成阴影的代码,在视图上效果很好(第一张图片) 在上下文中渲染或绘制后我需要相同的结果。
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
给你这个输出:
不过,我很想知道为什么阴影无法正确渲染。