我使用iTextSharp使用PdfAnnotation.CreateInk在PDF文档中绘制标记图形。我试图绘制矩形,传递五个坐标的数组。我知道iTextSharp有一个绘制矩形的专用函数,但我试图只使用一种方法来绘制我需要的各种标记行,而CeateInk似乎应该能够做到这一点。
问题是CreateInk是用曲线而不是角来绘制矩形。我还没有弄清楚如何改变它。 This answer表明解决方案可能是创建一个PdfAppearance;我还没弄清楚这是否有效。这是我的代码(第一位将点列表转换为数组数组,InkList需要):
public void MarkupInk(List<List<float>> InkList){
float[][] Coords = new float[InkList.Count][];
for (int i = 0; i < InkList.Count; i++) {
float[] thisarr = InkList [i].ToArray ();
Coords[i] = new float[InkList[i].Count];
System.Array.Copy (thisarr, Coords [i], InkList [i].Count);
}
using(MemoryStream ms = new MemoryStream ()){
PdfReader reader = new PdfReader (textmaster.pdfDocArr);
PdfStamper stamper = new PdfStamper (reader, ms);
pagerect = reader.GetPageSize (textmaster.currentfirstpage + 1);
PdfAnnotation an2 = PdfAnnotation.CreateInk (stamper.Writer, pagerect, "", Coords);
an2.Color = strokeColor;
an2.BorderStyle = new PdfBorderDictionary (strokeWeight, PdfBorderDictionary.STYLE_SOLID);
stamper.AddAnnotation (an2, textmaster.currentfirstpage+1);
stamper.Close ();
textmaster.pdfDocArr = ms.ToArray ();
reader.Close ();
}
}
非常感谢任何建议。谢谢!
编辑:关注@ mkl的代码我现在拥有创建带外观的PDF注释的代码。大多数注释都在我使用的查看应用程序中正确显示。但是有一种我无法解决的奇怪行为。
发生的事情是,在我创建另一个注释之前,最近创建的注释不会出现在查看应用程序中。因此,如果我创建注释A,它在我创建注释B之前是不可见的,此时注释A出现而B则不出现。创建注释C会导致注释B出现,依此类推。
即使我关闭pdf文件和查看应用程序并从磁盘重新加载,此行为仍然存在。因此,描述最后创建的注释的数据作为pdf文件的一部分存在,但在我创建新注释之前它不会呈现。
我怀疑在我用来创建注释和pdfAppearance的代码中我仍然缺少某些东西。这是创建单行注释的代码:
public void WriteLineAnnotation(List<float> polyCoords){
using (MemoryStream ms = new MemoryStream ()) {
PdfReader reader = new PdfReader (textmaster.pdfDocArr);
PdfStamper stamper = new PdfStamper (reader, ms) { AnnotationFlattening = true };
pagerect = reader.GetPageSize (textmaster.currentfirstpage + 1);
//Create the pdfAnnotation polyline
PdfAnnotation polyann = PdfAnnotation.CreatePolygonPolyline (stamper.Writer, pagerect, "", false, new PdfArray (polyCoords.ToArray ()));
polyann.Color = strokeColor;
polyann.BorderStyle = new PdfBorderDictionary (strokeWeight, PdfBorderDictionary.STYLE_SOLID);
polyann.Flags = iTextSharp.text.pdf.PdfAnnotation.FLAGS_PRINT;
//create the PdfAppearance and set attributes
PdfAppearance app = PdfAppearance.CreateAppearance (stamper.Writer, pagerect.Width, pagerect.Height);
app.SetColorStroke (strokeColor);
app.MoveTo (polyCoords [0], polyCoords [1]);
app.LineTo (polyCoords [2], polyCoords [3]);
app.Stroke ();
//set the annotation's appearance, add annotation, clean up
polyann.SetAppearance (PdfName.N, app);
stamper.AddAnnotation (polyann, textmaster.currentfirstpage + 1);
stamper.Close ();
reader.Close ();
//create bytearray from memorystream and send to pdf renderer
textmaster.pdfDocArr = ms.ToArray ();
}
}
[/代码]
有什么明显的东西我不见了吗?提前感谢您的帮助。
答案 0 :(得分:2)
我知道iTextSharp有一个绘制矩形的专用函数,但是我试图只使用一种方法来绘制我需要的各种标记行,而CeateInk似乎应该能够做到这一点。 / p>
请注意,iText不仅具有针对这些不同形式的单独功能,这些不同的功能还会创建不同类型的PDF注释。
特别是 Ink注释 - 您想要用于所有表单 - 被指定为
墨迹注释(PDF 1.3)表示由一个或多个不相交路径组成的徒手“涂鸦”。
(第12.5.6.13节 - 墨迹注释 - ISO 32000-1)
作为手绘“涂鸦”通常不被认为是一系列直线和尖角,而是更柔软和圆润;因此,PDF查看器显示由矩形的角的坐标给出的墨迹注释是自然的,其中曲线而不是角落。
当然,您可以使用外观流来提供外观的可视化,但这会轻微滥用此PDF功能。
相反,我建议您使用不同类型的注释来绘制所需的各种标记线:折线注释。它们被指定为:
多边形注释(PDF 1.5)在页面上显示闭合多边形。这样的多边形可以具有通过直线连接的任何数量的顶点。折线注释(PDF 1.5)与多边形类似,只是第一个和最后一个顶点不是隐式连接的。
(第12.5.6.9节 - 多边形和折线注释 - ISO 32000-1)
iText(夏普)也为这种注释提供了一种方法:
/**
* Creates a polygon or -line annotation
* @param writer the PdfWriter
* @param rect the annotation position
* @param contents the textual content of the annotation
* @param polygon if true, the we're creating a polygon annotation, if false, a polyline
* @param vertices an array with the vertices of the polygon or -line
* @since 5.0.2
*/
public static PdfAnnotation CreatePolygonPolyline(
PdfWriter writer, Rectangle rect, String contents, bool polygon, PdfArray vertices)
您可能最终仍然需要创建注释,因为并非所有PDF查看器,特别是所谓的&#34;预览者&#34;,都会生成外观,而是指望在预先显示的PDF中提供外观...
using (PdfReader pdfReader = new PdfReader(inputPath))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
{
PdfArray vertices = new PdfArray(new int[]{ 100, 100, 300, 300, 100, 300, 300, 100 });
PdfAnnotation polyLine = PdfAnnotation.CreatePolygonPolyline(pdfStamper.Writer, pdfReader.GetPageSize(1),
"", false, vertices);
polyLine.Color = BaseColor.GREEN;
pdfStamper.AddAnnotation(polyLine, 1);
}
补充一下:
在支持注释的PDF查看器中,包括根据规范生成外观。
using (PdfReader pdfReader = new PdfReader(inputPath))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
{
Rectangle pageSize = pdfReader.GetPageSize(1);
PdfArray vertices = new PdfArray(new int[] { 100, 100, 300, 300, 100, 300, 300, 100 });
PdfAnnotation polyLine = PdfAnnotation.CreatePolygonPolyline(pdfStamper.Writer, pageSize,
"", false, vertices);
polyLine.Color = BaseColor.GREEN;
PdfAppearance appearance = PdfAppearance.CreateAppearance(pdfStamper.Writer, pageSize.Width, pageSize.Height);
appearance.SetColorStroke(BaseColor.RED);
appearance.MoveTo(100, 100);
appearance.LineTo(300, 300);
appearance.LineTo(100, 300);
appearance.LineTo(300, 100);
appearance.Stroke();
polyLine.SetAppearance(PdfName.N, appearance);
pdfStamper.AddAnnotation(polyLine, 1);
}
添加此
在PDF查看器中支持根据规范带来注释的注释。
(我在外观上明确使用了不同的颜色,以确保PDF查看器显示我的外观,而不是自己创建一个。)