iOS 11 PDFKit Ink 注释 - 无法填充 UIBezierPath
iOS 11 PDFKit Ink annotation - cannot fill UIBezierPath
我正在使用带有子类型墨水的 PDFAnnotation() class 向 PDFDocument 添加墨水注释。这个想法是捕获使用触摸绘制的签名。
受 UberSignature 启发,我的 UIBezierPath 是一系列应该用颜色填充的矩形。但是,当我将注释添加到 PDFDocument 时,它没有被填充。
似乎 UIBezierPath 的 fill() 方法在添加到 PDFAnnotation 时什么都不做?
如果我使用相同的 UIBezierPath 并将其绘制在 UIImage 上,它会正确填充纯色。
有什么可能出错的想法吗?
有问题的代码:
UIColor.red.setStroke()
UIColor.red.setFill()
var path = UIBezierPath()
path.append(myRectangles)
path.fill()
var annotation = PDFAnnotation(bounds: path.bounds, forType: .ink, withProperties: nil)
annotation.add(path)
myPDFPage.addAnnotation(annotation)
在屏幕截图中,我尝试编写普通文本和两个示例行。左边的线画得慢,右边的线画得快。这个想法是让线条的宽度根据绘制的速度而变化,以使签名看起来更 natural/realistic.
InkAnnotation 呈现为描边路径的集合。没办法按照PDF reference 1.4 page 508.
填充颜色
Apple 的预览版使用 Stamp 注释将签名包含到 PDF 中。我尝试使用 PDFKit 对其进行逆向工程,但我看不到任何包含我放置在 PDF 中的签名的矢量数据。 PDFKit 在这里可能不够用。
(lldb) po annotation.annotationKeyValues
▿ 10 elements
▿ 0 : 2 elements
▿ key : AnyHashable("/AAPL:Hash")
- value : "/AAPL:Hash"
- value : /264236ab9aaabfe2d536167a89c26c2d
▿ 1 : 2 elements
▿ key : AnyHashable("/DA")
- value : "/DA"
- value : /Helvetica 12 Tf 0 g
▿ 2 : 2 elements
▿ key : AnyHashable("/T")
- value : "/T"
- value : Wojciech Nagrodzki
▿ 3 : 2 elements
▿ key : AnyHashable("/F")
- value : "/F"
- value : 4
▿ 4 : 2 elements
▿ key : AnyHashable("/Subtype")
- value : "/Subtype"
- value : /Stamp
▿ 5 : 2 elements
▿ key : AnyHashable("/Name")
- value : "/Name"
- value : /Draft
▿ 6 : 2 elements
▿ key : AnyHashable("/Rect")
- value : "/Rect"
- value : NSRect: {{5.8745389999999995, 748.38995}, {307.66119599999996, 87.648936000000049}}
▿ 7 : 2 elements
▿ key : AnyHashable("/Border")
- value : "/Border"
- value : PDFBorder: {solid lineWidth:2.8 hCorner:0.0 vCorner:0.0 dashCount:0 dashPattern:(
)}
▿ 8 : 2 elements
▿ key : AnyHashable("/Type")
- value : "/Type"
- value : /Annot
▿ 9 : 2 elements
▿ key : AnyHashable("/C")
- value : "/C"
- value : kCGColorSpaceModelRGB 0 0 0 1
您在当前图形上下文中用来填充路径的fill()
方法,这与注释无关。
如果使用图章注释失败,您还可以在图形上下文中呈现路径,将其转换为图像并放入 PDF 中。但我不确定你是否考虑过这一点。
您可以在 Adobe's archives.
中找到更多 PDF 参考资料
我设法找到了一个看起来相对最优的问题解决方案。
诀窍是创建 PDFAnnotation 的子类并覆盖 draw(with box:, in context:) 函数。在这个函数中,我可以使用 drawPath(using: .fill) 方法来填充贝塞尔曲线路径。
代码可以如下所示:
class SignatureAnnotation : PDFAnnotation {
public var myPath : UIBezierPath = UIBezierPath()
override func draw(with box: PDFDisplayBox, in context: CGContext) {
context.saveGState()
self.page?.transform(context, for: box)
context.beginPath()
context.setLineWidth(0.1)
context.setShouldAntialias(true)
context.addPath(self.myPath.cgPath.mutableCopy()!)
context.drawPath(using: .fill)
context.restoreGState()
}
}
将此注释(类型 .stamp)添加到 PDF 而不是墨迹注释,所有内容都将呈现为矢量(完全可缩放而不会被像素化)- 并且在保存时将与 PDF 的其余部分一起保存到文件或数据缓冲区。
唯一的缺点是UIBezierPath不能太复杂因为draw()函数耗时太长会引入闪烁。这可以通过简单地将 UIBezierPath 分成多个单独的路径来解决,每个路径都有自己的注释。
我正在使用带有子类型墨水的 PDFAnnotation() class 向 PDFDocument 添加墨水注释。这个想法是捕获使用触摸绘制的签名。
受 UberSignature 启发,我的 UIBezierPath 是一系列应该用颜色填充的矩形。但是,当我将注释添加到 PDFDocument 时,它没有被填充。
似乎 UIBezierPath 的 fill() 方法在添加到 PDFAnnotation 时什么都不做?
如果我使用相同的 UIBezierPath 并将其绘制在 UIImage 上,它会正确填充纯色。
有什么可能出错的想法吗?
有问题的代码:
UIColor.red.setStroke()
UIColor.red.setFill()
var path = UIBezierPath()
path.append(myRectangles)
path.fill()
var annotation = PDFAnnotation(bounds: path.bounds, forType: .ink, withProperties: nil)
annotation.add(path)
myPDFPage.addAnnotation(annotation)
在屏幕截图中,我尝试编写普通文本和两个示例行。左边的线画得慢,右边的线画得快。这个想法是让线条的宽度根据绘制的速度而变化,以使签名看起来更 natural/realistic.
InkAnnotation 呈现为描边路径的集合。没办法按照PDF reference 1.4 page 508.
填充颜色Apple 的预览版使用 Stamp 注释将签名包含到 PDF 中。我尝试使用 PDFKit 对其进行逆向工程,但我看不到任何包含我放置在 PDF 中的签名的矢量数据。 PDFKit 在这里可能不够用。
(lldb) po annotation.annotationKeyValues
▿ 10 elements
▿ 0 : 2 elements
▿ key : AnyHashable("/AAPL:Hash")
- value : "/AAPL:Hash"
- value : /264236ab9aaabfe2d536167a89c26c2d
▿ 1 : 2 elements
▿ key : AnyHashable("/DA")
- value : "/DA"
- value : /Helvetica 12 Tf 0 g
▿ 2 : 2 elements
▿ key : AnyHashable("/T")
- value : "/T"
- value : Wojciech Nagrodzki
▿ 3 : 2 elements
▿ key : AnyHashable("/F")
- value : "/F"
- value : 4
▿ 4 : 2 elements
▿ key : AnyHashable("/Subtype")
- value : "/Subtype"
- value : /Stamp
▿ 5 : 2 elements
▿ key : AnyHashable("/Name")
- value : "/Name"
- value : /Draft
▿ 6 : 2 elements
▿ key : AnyHashable("/Rect")
- value : "/Rect"
- value : NSRect: {{5.8745389999999995, 748.38995}, {307.66119599999996, 87.648936000000049}}
▿ 7 : 2 elements
▿ key : AnyHashable("/Border")
- value : "/Border"
- value : PDFBorder: {solid lineWidth:2.8 hCorner:0.0 vCorner:0.0 dashCount:0 dashPattern:(
)}
▿ 8 : 2 elements
▿ key : AnyHashable("/Type")
- value : "/Type"
- value : /Annot
▿ 9 : 2 elements
▿ key : AnyHashable("/C")
- value : "/C"
- value : kCGColorSpaceModelRGB 0 0 0 1
您在当前图形上下文中用来填充路径的fill()
方法,这与注释无关。
如果使用图章注释失败,您还可以在图形上下文中呈现路径,将其转换为图像并放入 PDF 中。但我不确定你是否考虑过这一点。
您可以在 Adobe's archives.
中找到更多 PDF 参考资料我设法找到了一个看起来相对最优的问题解决方案。
诀窍是创建 PDFAnnotation 的子类并覆盖 draw(with box:, in context:) 函数。在这个函数中,我可以使用 drawPath(using: .fill) 方法来填充贝塞尔曲线路径。
代码可以如下所示:
class SignatureAnnotation : PDFAnnotation {
public var myPath : UIBezierPath = UIBezierPath()
override func draw(with box: PDFDisplayBox, in context: CGContext) {
context.saveGState()
self.page?.transform(context, for: box)
context.beginPath()
context.setLineWidth(0.1)
context.setShouldAntialias(true)
context.addPath(self.myPath.cgPath.mutableCopy()!)
context.drawPath(using: .fill)
context.restoreGState()
}
}
将此注释(类型 .stamp)添加到 PDF 而不是墨迹注释,所有内容都将呈现为矢量(完全可缩放而不会被像素化)- 并且在保存时将与 PDF 的其余部分一起保存到文件或数据缓冲区。
唯一的缺点是UIBezierPath不能太复杂因为draw()函数耗时太长会引入闪烁。这可以通过简单地将 UIBezierPath 分成多个单独的路径来解决,每个路径都有自己的注释。