【问题标题】:Background Image and canvas with pencilKit Swiftui带有pencilKit Swiftui的背景图像和画布
【发布时间】:2020-12-03 10:01:50
【问题描述】:

我正在学习 PencilKit。

我有一个画布,我想设置一个我们可以在上面绘制的背景图像。

当我保存画布时,我希望我的背景图片可见

但我有一个错误: 无法将“Image”类型的值转换为预期的参数类型“UIImage?”

Image("badmintoncourt") 是我资产中的图像 我不知道如何解决它,但我可能没有以正确的方式将背景图像添加到我的画布

    struct Home : View {
    @State var canvas = PKCanvasView()
    @Environment(\.undoManager) private var undoManager
    @State var showingAlert = false
    var body: some View{
        
        NavigationView{
            MyCanvas(canvasView: canvas)
                .navigationTitle("Drawing")
                .navigationBarTitleDisplayMode(.inline)
        }
    }
  
}


struct MyCanvas: UIViewRepresentable {
    var canvasView: PKCanvasView
    let picker = PKToolPicker.init()
    
    func makeUIView(context: Context) -> PKCanvasView {
        self.canvasView.tool = PKInkingTool(.pen, color: .black, width: 15)
        self.canvasView.isOpaque = false
        self.canvasView.backgroundColor = UIColor.clear
        self.canvasView.becomeFirstResponder()

        let imageView = Image("badmintoncourt")

        let subView = self.canvasView.subviews[0]
            subView.addSubview(imageView)
            subView.sendSubviewToBack(imageView)
        return canvasView
    }
    
    func updateUIView(_ uiView: PKCanvasView, context: Context) {
        picker.addObserver(canvasView)
        picker.setVisible(true, forFirstResponder: uiView)
        DispatchQueue.main.async {
            uiView.becomeFirstResponder()
        }
    }
}

编辑: 这是我保存图像的代码:

func SaveImage(){
    let image = canvas.drawing.image(from: canvas.drawing.bounds, scale: 1)
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}

【问题讨论】:

    标签: swiftui background-image pencilkit


    【解决方案1】:

    Image 不是UIView,在这种情况下您必须使用UIImageView

        let imageView = UIImageView(image: UIImage(named: "badmintoncourt"))
    
        let subView = self.canvasView.subviews[0]
            subView.addSubview(imageView)
            subView.sendSubviewToBack(imageView)
    

    【讨论】:

    • 当我将画布保存到相册时,出现了背景图像,但背景图像不可见,这是怎么回事?
    • 这是一个不同的问题 ;) ...与 SwiftUI 无关。
    • 这是我的问题,;) 我要问一个新问题!
    【解决方案2】:

    这就是我解决此问题的方法,以允许在图像上绘制并将两者保存在一个最终图像中。这种解决方案使画布用于绘制图像的大小。

    我将画布添加为图像的叠加层,并将绘图存储在单独的图像中。完成绘图后,我将两个图像合并为一个。

    struct DrawOnImageView: View {
    
        @Binding var image: UIImage
    
        let onSave: (UIImage) -> Void
    
        @State private var drawingOnImage: UIImage = UIImage()
        @State private var canvasView: PKCanvasView = PKCanvasView()
    
        init(image: Binding<UIImage>, onSave: @escaping (UIImage) -> Void) {
            self.image = image
            self.onSave = onSave
        }
    
        var body: some View {
            VStack {
                Button(action: { save() }, label: Text("Save"))
    
                Image(uiImage: self.image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .edgesIgnoringSafeArea(.all)
                    .overlay(CanvasView(canvasView: $canvasView, onSaved: onChanged), alignment: .bottomLeading)
            }
        }
    
        private func onChanged() -> Void {
            self.drawingOnImage = canvasView.drawing.image(
                from: canvasView.bounds, scale: UIScreen.main.scale)
        }
    
        private func initCanvas() -> Void {
            self.canvasView = PKCanvasView();
            self.canvasView.isOpaque = false
            self.canvasView.backgroundColor = UIColor.clear
            self.canvasView.becomeFirstResponder()
        }
    
        private func save() -> Void {
            onSave(self.image.mergeWith(topImage: drawingOnImage))
        }
    }
    

    这个 UIImage 扩展将允许您合并图像。我使用了这个答案中的代码How to merge two UIImages?

    public extension UIImage {
        func mergeWith(topImage: UIImage) -> UIImage {
            let bottomImage = self
    
            UIGraphicsBeginImageContext(size)
    
    
            let areaSize = CGRect(x: 0, y: 0, width: bottomImage.size.width, height: bottomImage.size.height)
            bottomImage.draw(in: areaSize)
    
            topImage.draw(in: areaSize, blendMode: .normal, alpha: 1.0)
    
            let mergedImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return mergedImage
        }
    }
    

    最后,这是我的画布视图,尽管我认为您的代码中的 MyCanvas 应该可以正常工作。我的观点来自this PencilKit tutorial

    struct CanvasView {
        @Binding var canvasView: PKCanvasView
        let onSaved: () -> Void
    
        @State var toolPicker = PKToolPicker()
    }
    
    extension CanvasView: UIViewRepresentable {
        func makeUIView(context: Context) -> PKCanvasView {
            canvasView.tool = PKInkingTool(.pen, color: .gray, width: 10)
            #if targetEnvironment(simulator)
            canvasView.drawingPolicy = .anyInput
            #endif
            canvasView.delegate = context.coordinator
            showToolPicker()
            return canvasView
        }
    
        func updateUIView(_ uiView: PKCanvasView, context: Context) {}
    
        func makeCoordinator() -> Coordinator {
            Coordinator(canvasView: $canvasView, onSaved: onSaved)
        }
    }
    
    private extension CanvasView {
        func showToolPicker() {
            toolPicker.setVisible(true, forFirstResponder: canvasView)
            toolPicker.addObserver(canvasView)
            canvasView.becomeFirstResponder()
        }
    }
    
    class Coordinator: NSObject {
        var canvasView: Binding<PKCanvasView>
        let onSaved: () -> Void
    
        init(canvasView: Binding<PKCanvasView>, onSaved: @escaping () -> Void) {
            self.canvasView = canvasView
            self.onSaved = onSaved
        }
    }
    
    extension Coordinator: PKCanvasViewDelegate {
        func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
            if !canvasView.drawing.bounds.isEmpty {
                onSaved()
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-22
      • 2022-11-02
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多