如何在 UIImage 上描边?
How to stroke on UIImage?
我想连同笔触一起保存彩色形状,但下面的代码 (getImage()) 生成未描边的形状:
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1024, height: 1024))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
context.cgContext.strokePath()
}
}
return image
}
struct ShapeItem: Identifiable {
let id = UUID()
var color: UIColor = UIColor.white
var path: ScaledBezier
init(path: ScaledBezier) {
self.path = path
}
}
struct ScaledBezier: Shape {
let bezierPath: UIBezierPath
let sourceWidth: CGFloat
let sourceHeight: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path(bezierPath.cgPath)
// Figure out how much bigger we need to make our path in order for it to fill the available space without clipping.
let multiplier = min(rect.width/sourceWidth, rect.height/sourceHeight)
// Create an affine transform that uses the multiplier for both dimensions equally.
let transform = CGAffineTransform(scaleX: multiplier, y: multiplier)
// Apply that scale and send back the result.
path.closeSubpath()
return path.applying(transform)
}
}
有谁知道如何描边形状以便在 UIImage 上可见?
如果你想要描边和填充,那么你需要为每个路径使用如下
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1024, height: 1024))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.strokePath()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
}
}
return image
}
演示代码:
struct DemoView: View {
let shapeItemKeys = [1]
let shapeItemsByKey = [1: ShapeItem(path: ScaledBezier(bezierPath: UIBezierPath(roundedRect: CGRect(x: 10, y: 10, width: 100, height: 200), cornerRadius: 20), sourceWidth: 100, sourceHeight: 200))]
var body: some View {
VStack(spacing: 0) {
Image(uiImage: getImage())
}
}
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 300, height: 300))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.strokePath()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
}
}
return image
}
}
我想连同笔触一起保存彩色形状,但下面的代码 (getImage()) 生成未描边的形状:
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1024, height: 1024))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
context.cgContext.strokePath()
}
}
return image
}
struct ShapeItem: Identifiable {
let id = UUID()
var color: UIColor = UIColor.white
var path: ScaledBezier
init(path: ScaledBezier) {
self.path = path
}
}
struct ScaledBezier: Shape {
let bezierPath: UIBezierPath
let sourceWidth: CGFloat
let sourceHeight: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path(bezierPath.cgPath)
// Figure out how much bigger we need to make our path in order for it to fill the available space without clipping.
let multiplier = min(rect.width/sourceWidth, rect.height/sourceHeight)
// Create an affine transform that uses the multiplier for both dimensions equally.
let transform = CGAffineTransform(scaleX: multiplier, y: multiplier)
// Apply that scale and send back the result.
path.closeSubpath()
return path.applying(transform)
}
}
有谁知道如何描边形状以便在 UIImage 上可见?
如果你想要描边和填充,那么你需要为每个路径使用如下
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1024, height: 1024))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.strokePath()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
}
}
return image
}
演示代码:
struct DemoView: View {
let shapeItemKeys = [1]
let shapeItemsByKey = [1: ShapeItem(path: ScaledBezier(bezierPath: UIBezierPath(roundedRect: CGRect(x: 10, y: 10, width: 100, height: 200), cornerRadius: 20), sourceWidth: 100, sourceHeight: 200))]
var body: some View {
VStack(spacing: 0) {
Image(uiImage: getImage())
}
}
func getImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 300, height: 300))
let image = renderer.image { (context) in
for key in shapeItemKeys {
let currentShape = shapeItemsByKey[key]!
UIColor.black.setStroke()
context.stroke(renderer.format.bounds)
currentShape.color.setFill()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.strokePath()
context.cgContext.addPath(currentShape.path.bezierPath.cgPath)
context.cgContext.fillPath()
}
}
return image
}
}