【问题标题】:Creating a transparency group or setting graphics state soft mask with PDFBox使用 PDFBox 创建透明组或设置图形状态软遮罩
【发布时间】:2020-05-28 14:12:01
【问题描述】:

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

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

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

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


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

  • 蒙版图像为 200x200。它是用矩阵[[4 0 100] [0 4 100]]绘制的。
  • 图像为 400x300。它是用矩阵[[2 0 100] [0 2 150]] 绘制的。
  • 此外,在图像下方绘制了一个 400x400 的黑色方块,没有变换矩阵。

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

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

【问题讨论】:

    标签: pdf pdf-generation pdfbox mask


    【解决方案1】:

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

    【讨论】:

    • 非常感谢!我希望它非常手动,这不是问题。我通常会使用渐变,但我正在从另一种格式转换,所以我使用我正在转换的任何文件作为掩码。
    • 作为记录,在将要被屏蔽的对象直接绘制到页面内容流时,我在大多数查看器中遇到了渲染问题(它适用于单个对象)。所以我使用了第二个透明度组来对对象进行分组,以便将它们合成为单个对象。然后,我使用drawForm 将该组绘制到页面。
    猜你喜欢
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多