使用itextsharp突出显示pdf中的单词,而不是在浏览器中显示突出显示的单词

Kar*_*hik 1 c# syntax-highlighting itextsharp

使用itextsharp在浏览器中不显示突出显示的单词.

土砖

在此输入图像描述

浏览器

在此输入图像描述

 List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(splitText[i].Trim(), StringComparison.CurrentCultureIgnoreCase);
                    foreach (Rectangle rect in MatchesFound)
                    {
                        float[] quad = { rect.Left - 3.0f, rect.Bottom, rect.Right, rect.Bottom, rect.Left - 3.0f, rect.Top + 1.0f, rect.Right, rect.Top + 1.0f };
                        //Create our hightlight
                        PdfAnnotation highlight = PdfAnnotation.CreateMarkup(stamper.Writer, rect, null, PdfAnnotation.MARKUP_HIGHLIGHT, quad);
                        //Set the color
                        highlight.Color = BaseColor.YELLOW;
                       
                        //Add the annotation
                        stamper.AddAnnotation(highlight, pageno);
                        
                    }
Run Code Online (Sandbox Code Playgroud)

请帮我解决这个问题.

更新代码

  private void highlightPDF()
{
    //Create a simple test file
    string outputFile = Server.MapPath("~/pdf/16193037V_Dhana-FI_NK-QA_Completed.pdf");
    string filename = "HL" + Convert.ToString(Session["Filename"]) + ".pdf";
    Session["Filename"] = "HL" + Convert.ToString(Session["Filename"]);
    //Create a new file from our test file with highlighting
    string highLightFile = Server.MapPath("~/pdf/" + filename);

    //Bind a reader and stamper to our test PDF

    PdfReader reader = new PdfReader(outputFile);
    iTextSharp.text.pdf.PdfContentByte canvas;
    int pageno = Convert.ToInt16(txtPageno.Text);
    using (FileStream fs = new FileStream(highLightFile, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        using (PdfStamper stamper = new PdfStamper(reader, fs))
        {
            canvas = stamper.GetUnderContent(pageno);
            myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
            strategy.UndercontentCharacterSpacing = canvas.CharacterSpacing;
            strategy.UndercontentHorizontalScaling = canvas.HorizontalScaling;

            string currentText = PdfTextExtractor.GetTextFromPage(reader, pageno, strategy);
            string text = txtHighlight.Text.Replace("\r\n", "").Replace("\\n", "\n").Replace("  ", " ");
            string[] splitText = text.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < splitText.Length; i++)
            {
                List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(splitText[i].Trim(), StringComparison.CurrentCultureIgnoreCase);
                foreach (Rectangle rect in MatchesFound)
                {
                    canvas.SaveState();
                    canvas.SetColorFill(BaseColor.YELLOW);
                    canvas.Rectangle(rect);
                    canvas.Fill();
                    canvas.RestoreState();                      
                }
            }

        }
    }
    reader.Close();      


}
Run Code Online (Sandbox Code Playgroud)

它没有突出显示文本.我通过了文本和页面no来突出显示文本.

mkl*_*mkl 6

首先...

为什么OP的(更新的)代码不起作用

实际上有两个因素.

首先, OP的代码中存在一个问题,即在他使用的路径中添加一个矩形

canvas.Rectangle(rect);
Run Code Online (Sandbox Code Playgroud)

不幸的是,这并不是他所期望的:Rectangle该类具有超出矩形的仅仅坐标的多个属性,最重要的是关于所选边框,边框颜色和内部颜色的信息,并PdfContentByte.Rectangle(Rectangle)根据这些属性绘制矩形.

但是,在这种情况下,rect仅用于传输矩形的坐标,因此这些附加属性都是falsenull.因此,canvas.Rectangle(rect)什么都不做!

相反,OP应该使用

canvas.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
Run Code Online (Sandbox Code Playgroud)

这里.

此外,@布鲁诺在他的回答中提到

请注意,如果将其添加到不透明形状(例如图像下方)下,则不会看到黄色矩形.

不幸的是,这就是这种情况:文档实际上是一个扫描文档,每个页面都是一个页面填充图像,在该图像下绘制等效文本(可能在OCR之后)以允许文本复制和粘贴.

因此,无论OP的代码如何绘制UnderContent,它都将被该图像隐藏.

因此,让我们尝试不同的东西......

如何使它工作

@Bruno在他的回答中也指出了这种情况的解决方案:

在这种情况下,您可以在现有内容的顶部添加透明矩形.

遵循这个建议我们更换

canvas = stamper.GetUnderContent(pageno);
Run Code Online (Sandbox Code Playgroud)

通过

canvas = stamper.GetOverContent(pageno);

PdfGState state = new PdfGState();
state.FillOpacity = .3f;
canvas.SetGState(state);
Run Code Online (Sandbox Code Playgroud)

在第三个文档页面上选择"支持"一词,我们得到:

使用.3的不透明度

这里的黄色很苍白.

使用相反的Opacity.6我们得到

使用.6的不透明度

现在黄色更强烈但文字开始变得苍白.

对于这样的任务,我实际上更喜欢使用混合模式Darken.这可以通过使用来完成

state.BlendMode = new PdfName("Darken");
Run Code Online (Sandbox Code Playgroud)

而不是state.FillOpacity = .3f.这导致了

使用混合模式变暗

这个IMO看起来更好.

客户如何做到这一点

OP评论道

客户给出了pdf.在那里,他们突出显示文本,突出显示的文本显示在浏览器中

客户端的PDF实际上使用注释,就像他原始代码中的OP一样,但相比之下,每个客户端的注释都包含一个外观流,iText生成的高亮注释没有.

提供外观是可选的,如果没有给出,PDF查看器确实应该生成外观.显然,有许多PDF查看器依赖于PDF带来的外观.

顺便说一下,客户端PDF中的外观实际上使用了混合模式Multiply.对于底层的白色和黑色,DarkenMultiply具有相同的结果.

使其与注释一起使用

在评论中,OP想知道

请再疑一问,如果用户错误地突出显示如何删除黄色(或将黄色变为白色)?我把黄色变成了白色,但它没有用.canvas.SetColorFill(BaseColor.WHITE);

撤消对页面内容的更改通常比撤消添加注释更困难.因此,让我们使OP的原始代码也起作用,即在高亮注释中添加外观流.

正如OP在另一条评论中报道的那样,他首次尝试添加外观流失败了:

PdfAppearance appearance = PdfAppearance.CreateAppearance(stamper.Writer, rect.Width, rect.Height);
appearance.Rectangle(rect.Left, rect.Bottom, rect.Width, rect.Height);
appearance.SetColorFill(BaseColor.WHITE);
appearance.Fill();
highlight.SetAppearance( PdfAnnotation.APPEARANCE_NORMAL, appearance );
stamper.AddAnnotation(highlight, pageno);
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

他尝试的问题是:

  • 外观模板的原点位于注释区域的左下角,而不是页面的左下角.因此,要为相关区域着色,矩形的左下角必须为(0,0).
  • 严格地说,必须开始路径构建之前设置颜色.
  • 应使用与白色不同的颜色进行突出显示.
  • 应使用透明度或适当的渲染模式,以允许原始的标记文本通过.

因此,以下代码显示了如何执行此操作.

private void highlightPDFAnnotation(string outputFile, string highLightFile, int pageno, string[] splitText)
{
    PdfReader reader = new PdfReader(outputFile);
    iTextSharp.text.pdf.PdfContentByte canvas;
    using (FileStream fs = new FileStream(highLightFile, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        using (PdfStamper stamper = new PdfStamper(reader, fs))
        {
            myLocationTextExtractionStrategy strategy = new myLocationTextExtractionStrategy();
            strategy.UndercontentHorizontalScaling = 100;

            string currentText = PdfTextExtractor.GetTextFromPage(reader, pageno, strategy);
            for (int i = 0; i < splitText.Length; i++)
            {
                List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(splitText[i].Trim(), StringComparison.CurrentCultureIgnoreCase);
                foreach (Rectangle rect in MatchesFound)
                {
                    float[] quad = { rect.Left - 3.0f, rect.Bottom, rect.Right, rect.Bottom, rect.Left - 3.0f, rect.Top + 1.0f, rect.Right, rect.Top + 1.0f };
                    //Create our hightlight
                    PdfAnnotation highlight = PdfAnnotation.CreateMarkup(stamper.Writer, rect, null, PdfAnnotation.MARKUP_HIGHLIGHT, quad);
                    //Set the color
                    highlight.Color = BaseColor.YELLOW;

                    PdfAppearance appearance = PdfAppearance.CreateAppearance(stamper.Writer, rect.Width, rect.Height);
                    PdfGState state = new PdfGState();
                    state.BlendMode = new PdfName("Multiply");
                    appearance.SetGState(state);
                    appearance.Rectangle(0, 0, rect.Width, rect.Height);
                    appearance.SetColorFill(BaseColor.YELLOW);
                    appearance.Fill();

                    highlight.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, appearance);

                    //Add the annotation
                    stamper.AddAnnotation(highlight, pageno);
                }
            }
        }
    }
    reader.Close();
}
Run Code Online (Sandbox Code Playgroud)

这些注释也由Chrome显示,作为注释,它们可以轻松删除.