我已经为这个问题苦苦挣扎了好几天了。我希望这里有人可以提供帮助。
我的文件流中有一个 PDF 文档,我想使用 C# 中的 iText7 8.0.3 查找关键字“and”的所有实例,并用红色背景突出显示它们,然后将文档保存回内存流然后到 pdf 副本。
这是我的代码,几乎可以工作,它确实渲染了红色背景,但只是在错误的相对位置:-
using iText.Kernel.Colors;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Kernel.Pdf.Canvas.Parser;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
using System.IO;
FileStream src = new FileStream("C:\\Temp\\34207180.pdf", FileMode.Open);
MemoryStream ms = new MemoryStream();
string keyword = "and";
PdfDocument pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(ms));
int pdfPages = pdfDoc.GetNumberOfPages();
for (int page = 1; page <= pdfPages; page++)
{
Regex regex = new Regex(keyword, RegexOptions.IgnoreCase);
RegexBasedLocationExtractionStrategy extractionStrategy = new RegexBasedLocationExtractionStrategy(regex);
PdfCanvasProcessor parser = new PdfCanvasProcessor(extractionStrategy);
parser.ProcessPageContent(pdfDoc.GetPage(page));
List<IPdfTextLocation> locs = extractionStrategy.GetResultantLocations().ToList();
PdfCanvas pdfCanvas = new PdfCanvas(pdfDoc.GetPage(page).NewContentStreamAfter(), pdfDoc.GetPage(page).GetResources(), pdfDoc);
foreach (var l in locs)
{
pdfCanvas
.SaveState()
.SetFillColor(ColorConstants.RED)
.Rectangle(l.GetRectangle().GetX(), l.GetRectangle().GetY(), l.GetRectangle().GetWidth(), l.GetRectangle().GetHeight())
.Fill()
.RestoreState();
}
}
pdfDoc.Close();
byte[] img = ms.ToArray();
File.WriteAllBytes("C:\\Temp\\34207180-dest.pdf", img);
谁能解释一下这是怎么回事?就像 GetResultantLocations 返回的值的比例与 PdfCanvas 矩形填充所需的比例不同。
我在这个网站和其他地方阅读了很多文章,但没有解决。
你所做的绘图会受到原始内容中设置的变换矩阵的影响。
为了不受任何活动变换矩阵的影响,您可以使用 Canvas PdfCanvas(PdfPage page, boolwrappOldContent)。这将包装现有内容并恢复到原始状态。
绘制的矩形将遮挡文本。这可以通过将混合模式设置为相乘来解决。
Canvas.SetExtGState(new PdfExtGState().SetBlendMode(PdfExtGState.BM_MULTIPLY))
我更新了您的部分代码以反映这些和其他一些更改:
PdfCanvas pdfCanvas = new PdfCanvas(pdfDoc.GetPage(page), true);
pdfCanvas.SaveState();
pdfCanvas.SetFillColor(ColorConstants.RED);
pdfCanvas.SetExtGState(new PdfExtGState().SetBlendMode(PdfExtGState.BM_MULTIPLY));
foreach (var l in locs)
{
pdfCanvas
.Rectangle(l.GetRectangle().GetX(), l.GetRectangle().GetY(), l.GetRectangle().GetWidth(),
l.GetRectangle().GetHeight())
.Fill();
}
pdfCanvas.RestoreState();