使用 PDFBox 创建透明组或设置图形状态软遮罩

Creating a transparency group or setting graphics state soft mask with PDFBox

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

掩码和对象不一定使用相同的变换矩阵,并且可能有多个对象需要掩码,因此排除了使用 ImageXObject 字典的 SMask 属性的可能性。

所以在阅读了一些 PDF 规范之后,看起来我应该做以下事情:用要遮罩的对象创建一个透明组,然后用在图形状态上设置的软遮罩来绘制它。

这行得通吗?我怎样才能做到这一点,最好是使用 PDFBox?


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

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

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

据我所知,在 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 渐变。结果很可能像素化要少得多。