您可以尝试通过传递函数实现类似的功能(参见 ISO 32000-1 第 10.4 节)。
产生的效果例如可以是这样的(左上角是原始内容):
这是使用以下代码创建的
try (PDDocument pdDocument = new PDDocument()) {
PDPage pdPage = new PDPage();
pdDocument.addPage(pdPage);
PDImageXObject pdImage = [... create image XObject ...];
try (PDPageContentStream canvas = new PDPageContentStream(pdDocument, pdPage)) {
canvas.drawImage(pdImage, 0, 600, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ neg 1 add }"));
canvas.drawImage(pdImage, 150, 600, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul cos }"));
canvas.drawImage(pdImage, 300, 600, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul sin neg 1 add }"));
canvas.drawImage(pdImage, 450, 600, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ .5 mul }"));
canvas.drawImage(pdImage, 0, 450, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul cos neg 1 add }"));
canvas.drawImage(pdImage, 150, 450, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul sin }"));
canvas.drawImage(pdImage, 300, 450, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ .5 mul .5 add }"));
canvas.drawImage(pdImage, 450, 450, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ }", "{ pop 1 }", "{ pop 1 }", "{ pop 1 }"));
canvas.drawImage(pdImage, 0, 300, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ }", "{ pop 1 }", "{ pop 1 }"));
canvas.drawImage(pdImage, 150, 300, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ pop 1 }", "{ }", "{ pop 1 }"));
canvas.drawImage(pdImage, 300, 300, 150, 150);
canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ pop 1 }", "{ pop 1 }", "{ }"));
canvas.drawImage(pdImage, 450, 300, 150, 150);
}
pdDocument.save("SimpleTransferExample.pdf");
}
(ApplyTransferFunction 测试testSimpleTransferExample)
使用这些辅助方法:
PDExtendedGraphicsState createTransferedState(String function) throws IOException {
PDExtendedGraphicsState transferedState = new PDExtendedGraphicsState();
transferedState.setTransfer(createTransferFunction(function).getCOSObject());
return transferedState;
}
PDExtendedGraphicsState createTransferedState(String function1, String function2, String function3, String function4) throws IOException {
COSArray array = new COSArray();
array.add(createTransferFunction(function1).getCOSObject());
array.add(createTransferFunction(function2).getCOSObject());
array.add(createTransferFunction(function3).getCOSObject());
array.add(createTransferFunction(function4).getCOSObject());
PDExtendedGraphicsState transferedState = new PDExtendedGraphicsState();
transferedState.setTransfer(array);
return transferedState;
}
PDFunctionType4 createTransferFunction(String function) throws IOException {
return createFunction(function, new float[] {0f, 1.0f}, new float[] {0f, 1.0f});
}
/** @see org.apache.pdfbox.pdmodel.common.function.TestPDFunctionType4 */
PDFunctionType4 createFunction(String function, float[] domain, float[] range) throws IOException {
COSStream stream = new COSStream();
stream.setInt("FunctionType", 4);
COSArray domainArray = new COSArray();
domainArray.setFloatArray(domain);
stream.setItem("Domain", domainArray);
COSArray rangeArray = new COSArray();
rangeArray.setFloatArray(range);
stream.setItem("Range", rangeArray);
try (OutputStream out = stream.createOutputStream()) {
byte[] data = function.getBytes(StandardCharsets.US_ASCII);
out.write(data, 0, data.length);
}
return new PDFunctionType4(stream);
}
(来自ApplyTransferFunction 的辅助方法)
因此,
有没有办法对 PDF 页面内容(颜色)做同样的操作?
是的,只需在页面内容的开头应用您选择的传递函数,即将它添加到您使用 AppendMode.PREPEND 为页面创建的 PDPageContentStream 中。