首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java itext7水印文本隐藏在图像后面

java itext7水印文本隐藏在图像后面
EN

Stack Overflow用户
提问于 2022-01-02 08:38:36
回答 1查看 229关注 0票数 2

我试图在pdf中使用itext添加水印。使用以下代码可以正常工作:

代码语言:javascript
复制
import com.itextpdf.io.font.constants.StandardFonts;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.colors.PatternColor;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.canvas.PdfPatternCanvas;
import com.itextpdf.kernel.pdf.colorspace.PdfPattern;
import com.itextpdf.kernel.pdf.colorspace.PdfPattern.Tiling;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;


public class TestNewPdf {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        
        
        
        
          PdfReader reader = new PdfReader("F:/barcode/test.pdf");        
          PdfWriter writer = new PdfWriter("F:/barcode/outputTest.pdf");
        
        
        PdfDocument pdfDocument = new PdfDocument(reader,writer);
    
        PdfPattern.Tiling tiling = new Tiling(new Rectangle(220, 100));
        new Canvas(new PdfPatternCanvas(tiling, pdfDocument), pdfDocument, tiling.getBBox()).add(new Paragraph("franco")
                .setFontColor(ColorConstants.RED)
                .setBold()
                .setFont(PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD))
                .setFontSize(10f)
                .setRotationAngle(Math.PI / 10)
                );

        for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
            PdfPage page = pdfDocument.getPage(i);
            
            new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDocument)
                    .saveState()
                    
                    .setFillColor(new PatternColor(tiling))
                    .rectangle(page.getCropBox())
                    .fill()
                    .restoreState();
        }

        pdfDocument.close();
        
        
    }
    
    
    
    

}

但是,当源pdf包含图像或源pdf是扫描文件时,我有一个问题,这意味着pdf变得像图像。

水印文本隐藏在图像后面。

有人能帮我解决这个问题吗?

更新:

在某些情况下,水印覆盖内容,如何使文本更加透明。我对代码进行了更新,但没有成功,以使水印更加透明。

我试着用这个代码:

代码语言:javascript
复制
  PdfFont helvetica = PdfFontFactory.createFont();
          
        PdfDocument pdfDocument = new PdfDocument(reader,writer);
        
    
        PdfPattern.Tiling tiling = new Tiling(new Rectangle(220, 100));
        new Canvas(new PdfPatternCanvas(tiling, pdfDocument), pdfDocument, tiling.getBBox()).add(new Paragraph("uhatem")
                
                   .setFontColor(ColorConstants.GRAY)
                   .setFont(helvetica)
                   .setFontSize(15f)
                .setRotationAngle(Math.PI / 10)
                );

        for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
            PdfPage page = pdfDocument.getPage(i);
            new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument)
                    .saveState()
                    
                    .setFillColor(new PatternColor(tiling))
                    .rectangle(page.getCropBox())
                    .fill()
                    .restoreState();
        }

        pdfDocument.close();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-02 11:03:24

您可以使用page.newContentStreamBefore()为您的水标记添加内容流。因此,在绘制页面时,首先绘制水印,然后在其上绘制内容。对于通常的文本和稀疏矢量图形,这是好的,但对于覆盖内容的全部区域,水印可能是完全隐藏的。

尝试使用page.newContentStreamAfter()代替。但是要小心,你可能不想再加粗的水印文本了,甚至可能只限于大纲,因为标记现在涵盖了内容。

在问题更新和评论中,您询问了如何

使文本透明。

透明度通常是通过选择匹配的扩展图形状态来实现的,例如:

代码语言:javascript
复制
PdfExtGState extGState = new PdfExtGState().setBlendMode(new PdfName("Multiply"));
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
    PdfPage page = pdfDocument.getPage(i);
    new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument)
            .saveState()
            .setExtGState(extGState)
            .setFillColor(new PatternColor(tiling))
            .rectangle(page.getCropBox())
            .fill()
            .restoreState();

(https://github.com/mkl-public/testarea-itext7/blob/master/src/test/java/mkl/testarea/itext7/content/AddWatermark.java#L87 test testAddLikeFrancoImproved__)

您可以尝试找出您想要使用混合模式(这里的示例中是“乘”)还是alpha值透明度(使用setFillOpacitysetStrokeOpacity而不是setBlendMode设置)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70554618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档