以 45 度角穿过 Apache PDFBox 中心旋转水印文本

abh*_*rya 2 java pdfbox

我想使用 PDFBox API 添加文本到 PDF 并将其旋转 45 度并将其放置在页面的中心,文本是动态的,应该始终放置在中心,除了居中部分之外,其他所有功能都可以工作,我将不胜感激任何帮助。我有这个代码:

Point2D.Float pageCenter = getCenter(page);

float stringWidth = getStringWidth(watermarkText, font, fontSize);
float textX = pageCenter.x - stringWidth / 2F + center.x;
System.out.println(textX);
float textY = pageCenter.y + center.y;
//System.out.println("Inside cross"+textX+", "+textY);
fontSize = 110.0f;  
cs.transform(Matrix.getRotateInstance(Math.toRadians(45), textX, textY));
cs.moveTo(0, 0);
cs.lineTo(125, 0);
r0.setNonStrokingAlphaConstant(0.20f);
Run Code Online (Sandbox Code Playgroud)

这就是我想要的结果: 输出PDF

Til*_*err 5

我所做的是首先根据计算出的角度进行旋转。在这个“旋转的世界”中,我进行水平偏移,使文本位于中间,并将文本垂直移动一点,使其位于想象的对角线的“垂直”中间(“水平”中)旋转的世界”)。

try (PDDocument doc = new PDDocument())
{
    PDPage page = new PDPage();
    doc.addPage(page);

    PDFont font = PDType1Font.HELVETICA_BOLD;
    try (PDPageContentStream cs =
            new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true))
        // use this long constructor when working on existing PDFs
    {
        float fontHeight = 110;
        String text = "Watermark";

        float width = page.getMediaBox().getWidth();
        float height = page.getMediaBox().getHeight();
        int rotation = page.getRotation();
        switch (rotation)
        {
            case 90:
                width = page.getMediaBox().getHeight();
                height = page.getMediaBox().getWidth();
                cs.transform(Matrix.getRotateInstance(Math.toRadians(90), height, 0));
                break;
            case 180:
                cs.transform(Matrix.getRotateInstance(Math.toRadians(180), width, height));
                break;
            case 270:
                width = page.getMediaBox().getHeight();
                height = page.getMediaBox().getWidth();
                cs.transform(Matrix.getRotateInstance(Math.toRadians(270), 0, width));
                break;
            default:
                break;
        }
        float stringWidth = font.getStringWidth(text) / 1000 * fontHeight;
        float diagonalLength = (float) Math.sqrt(width * width + height * height);
        float angle = (float) Math.atan2(height, width);
        float x = (diagonalLength - stringWidth) / 2; // "horizontal" position in rotated world
        float y = -fontHeight / 4; // 4 is a trial-and-error thing, this lowers the text a bit
        cs.transform(Matrix.getRotateInstance(angle, 0, 0));
        cs.setFont(font, fontHeight);
        //cs.setRenderingMode(RenderingMode.STROKE); // for "hollow" effect
        
        PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
        gs.setNonStrokingAlphaConstant(0.2f);
        gs.setStrokingAlphaConstant(0.2f);
        gs.setBlendMode(BlendMode.MULTIPLY);
        cs.setGraphicsStateParameters(gs);
        
        // some API weirdness here. When int, range is 0..255.
        // when float, this would be 0..1f
        cs.setNonStrokingColor(255, 0, 0);
        cs.setStrokingColor(255, 0, 0);

        cs.beginText();
        cs.newLineAtOffset(x, y);
        cs.showText(text);
        cs.endText();
    }
    doc.save("watermarked.pdf");
}
Run Code Online (Sandbox Code Playgroud)

请注意,我设置了抚摸和非抚摸(=填充)。这对于想要尝试(禁用的)“空心”外观(仅使用抚摸)的人很有用。默认模式是填充,即非描边。