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

时间:2018-11-01 19:30:57

标签: 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);

这是我想要的结果: Output PDF

1 个答案:

答案 0 :(得分:2)

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

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.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
        // gs.setBlendMode(BlendMode.MULTIPLY); // will work in 2.0.14
        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");
}

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