pdf - 使用 PDFBox 创建透明组或设置图形状态软遮罩
问题描述
我有一个用作软蒙版的灰度图像,我想在一组 PDF 对象(图像或路径)上使用它。
掩码和对象不一定使用相同的变换矩阵,可能有多个对象需要掩码,从而排除了使用SMask
ImageXObject 字典属性的可能性。
因此,在阅读了一些 PDF 规范之后,看起来我应该执行以下操作:使用要遮罩的对象创建一个透明度组,然后使用在图形状态上设置的软遮罩来绘制它。
那会奏效吗?我怎样才能做到这一点,最好是使用 PDFBox?
这是一个例子。我有这两个图像:面具和另一个图像。
- 蒙版图像为 200x200。它是用矩阵绘制的
[[4 0 100] [0 4 100]]
。 - 图像为 400x300。它是用矩阵绘制的
[[2 0 100] [0 2 150]]
。 - 此外,在图像下方绘制了一个 400x400 的黑色方块,没有变换矩阵。
因此,使用图像和正方形创建了一个透明度组,然后使用蒙版图像绘制它。这是预期的结果:
就效果而言,相当丑陋,但这只是一个例子。
解决方案
据我所知,在 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 渐变。结果很可能会少得多像素化。
推荐阅读
- sql - 将逗号分隔的水平字符串转换为垂直字符串
- api - 在 Postman API 记录器响应数据不可见
- angular - angular-tree-component 创建上下文菜单
- java - ANTLR4 getCharPositionInLine() 在 LEXER 规则中没有按预期工作
- python - 从最大概率的二元模型中获取下一个单词
- java - 使用 Java API 为 CPU 配置 Tensorflow
- r - R:基于同一数据帧中另一个因素的 NROW 对数据帧的子集进行子集化
- javascript - ES6 类原型 - 类型解析
- react-select - React-Select v2.0.0 历史混乱?
- flutter - 如何将值添加到从颤振到 Firestore 的数组中