首页 > 解决方案 > 使用 PDFBox 创建透明组或设置图形状态软遮罩

问题描述

我有一个用作软蒙版的灰度图像,我想在一组 PDF 对象(图像或路径)上使用它。

掩码和对象不一定使用相同的变换矩阵,可能有多个对象需要掩码,从而排除了使用SMaskImageXObject 字典属性的可能性。

因此,在阅读了一些 PDF 规范之后,看起来我应该执行以下操作:使用要遮罩的对象创建一个透明度组,然后使用在图形状态上设置的软遮罩来绘制它。

那会奏效吗?我怎样才能做到这一点,最好是使用 PDFBox?


这是一个例子。我有这两个图像:面具和另一个图像。

面具 图片

因此,使用图像和正方形创建了一个透明度组,然后使用蒙版图像绘制它。这是预期的结果:

结果

就效果而言,相当丑陋,但这只是一个例子。

标签: pdfpdf-generationpdfboxmask

解决方案


据我所知,在 PDFBox 中建立扩展图形状态软掩码是一项非常手动的任务。你可以这样做:

try (   PDDocument document = new PDDocument()  ) {
    final PDImageXObject image = RETRIEVE PHOTO IMAGE;
    final PDImageXObject mask = RETRIEVE MASK IMAGE;

    PDTransparencyGroupAttributes transparencyGroupAttributes = new PDTransparencyGroupAttributes();
    transparencyGroupAttributes.getCOSObject().setItem(COSName.CS, COSName.DEVICEGRAY);

    PDTransparencyGroup transparencyGroup = new PDTransparencyGroup(document);
    transparencyGroup.setBBox(PDRectangle.A4);
    transparencyGroup.setResources(new PDResources());
    transparencyGroup.getCOSObject().setItem(COSName.GROUP, transparencyGroupAttributes);
    try (   PDFormContentStream canvas = new PDFormContentStream(transparencyGroup)   ) {
        canvas.drawImage(mask, new Matrix(400, 0, 0, 400, 100, 100));
    }

    COSDictionary softMaskDictionary = new COSDictionary();
    softMaskDictionary.setItem(COSName.S, COSName.LUMINOSITY);
    softMaskDictionary.setItem(COSName.G, transparencyGroup);

    PDExtendedGraphicsState extendedGraphicsState = new PDExtendedGraphicsState();
    extendedGraphicsState.getCOSObject().setItem(COSName.SMASK, softMaskDictionary);

    PDPage page = new PDPage(PDRectangle.A4);
    document.addPage(page);
    try (   PDPageContentStream canvas = new PDPageContentStream(document, page)   ) {
        canvas.saveGraphicsState();
        canvas.setGraphicsStateParameters(extendedGraphicsState);
        canvas.setNonStrokingColor(Color.BLACK);
        canvas.addRect(100, 100, 400, 400);
        canvas.fill();
        canvas.drawImage(image, new Matrix(400, 0, 0, 300, 100, 150));
        canvas.restoreGraphicsState();
    }

    document.save(new File(RESULT_FOLDER, "SoftMaskedImageAndRectangle.pdf"));
}

结果:

截屏

不过,如果我是你,我不会使用位图图像作为软蒙版,而是使用 PDF 渐变。结果很可能会少得多像素化。


推荐阅读