iTextSharp CreateInk方法:曲线和角点

时间:2017-02-12 11:49:46

标签: c# itext

我使用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 ();
    }
}

[/代码]

有什么明显的东西我不见了吗?提前感谢您的帮助。

1 个答案:

答案 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);
}

补充一下:

Screenshot

在支持注释的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);
}

添加此

Screenshot

在PDF查看器中支持根据规范带来注释的注释。

(我在外观上明确使用了不同的颜色,以确保PDF查看器显示我的外观,而不是自己创建一个。)