簡體   English   中英

如何在不丟失陰影飽和度的情況下將帶陰影的 UIBezierpath 轉換為 UIImage

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM