如何使用iText7 C#实现PDF的Knockout(挖空)效果?
解决iText7 C#实现PDF挖空(Knockout)效果的问题
你的代码无法生效的核心原因是:挖空效果需要在同一个透明组内的多个重叠元素之间才会触发,而你将整个源页面作为单个XObject添加到透明组中,组内仅包含一个元素,自然无法产生挖空效果。
挖空效果的生效逻辑
当同一个PdfTransparencyGroup(透明组)中存在多个重叠的图形/文本元素,且组的Knockout属性设为true时,后续绘制的元素会“挖掉”前面的元素,露出组下方的页面内容(而非混合颜色)。
修正后的代码示例
场景1:在新PDF中手动绘制重叠元素实现挖空
如果需要从零开始创建带挖空效果的PDF:
var targetFPath = @"out.pdf"; using (PdfDocument destPdf = new PdfDocument(new PdfWriter(targetFPath))) { PdfPage page = destPdf.AddNewPage(PageSize.A4); PdfCanvas canvas = new PdfCanvas(page); // 创建启用挖空的透明组 PdfTransparencyGroup transGroup = new PdfTransparencyGroup(); transGroup.SetKnockout(true); // 保存画布状态,开启透明组 canvas.SaveState(); canvas.SetGroup(transGroup); // 绘制第一个元素(红色背景矩形) canvas.SetFillColor(ColorConstants.RED) .Rectangle(100, 100, 300, 300) .Fill(); // 绘制第二个元素(白色矩形,挖空红色背景) canvas.SetFillColor(ColorConstants.WHITE) .Rectangle(150, 150, 200, 200) .Fill(); // 恢复画布状态 canvas.RestoreState(); }
场景2:将源PDF的重叠元素放入透明组实现挖空
如果源PDF本身包含需要挖空的重叠元素,需要将这些元素包裹到启用挖空的透明组中:
var sourceFPath = @"to_knockout.pdf"; var targetFPath = @"out.pdf"; using (PdfDocument origPdf = new PdfDocument(new PdfReader(sourceFPath))) using (PdfDocument destPdf = new PdfDocument(new PdfWriter(targetFPath))) { PdfPage origPage = origPdf.GetPage(1); PageSize pageSize = origPage.GetPageSize(); PdfPage destPage = destPdf.AddNewPage(pageSize); PdfCanvas canvas = new PdfCanvas(destPage); // 创建Form XObject并配置挖空透明组 PdfFormXObject formXObject = new PdfFormXObject(pageSize); PdfTransparencyGroup transGroup = new PdfTransparencyGroup(); transGroup.SetKnockout(true); formXObject.SetGroup(transGroup); // 将源页面内容复制到XObject中,确保元素处于同一透明组内 PdfCanvas xObjCanvas = new PdfCanvas(formXObject, destPdf); xObjCanvas.AddXObjectAt(origPage.CopyAsFormXObject(destPdf), 0, 0); // 将配置好的XObject添加到目标页面 canvas.AddXObjectAt(formXObject, 0, 0); }
额外说明
如果修正后仍无效果,需检查:
- 源PDF中是否存在真正重叠的元素(而非视觉上的重叠)
- 源PDF元素是否已有独立的透明设置,导致挖空规则被覆盖
内容的提问来源于stack exchange,提问作者zhusp
相关产品推荐
相关产品推荐

